Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add initial brand support #431

Merged
merged 12 commits into from
May 7, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'brand_bloc.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import 'package:bloc/bloc.dart';
import 'package:catalyst_voices_brands/catalyst_voices_brands.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';

part 'brand_event.dart';
part 'brand_state.dart';

/// [BrandBloc] is a Bloc responsible for managing the brand state.
///
/// This Bloc listens for [BrandEvent]s and updates the [BrandState]
/// accordingly.
/// The [BrandState] can be consumed by the [MaterialApp] to build the
/// appropriate [ThemeData] based on the [BrandKey] stored in the state.
///
/// To build the appropriate [ThemeData] based on the [BrandKey] is
/// possible to use the [ThemeBuilder] utility form the `catalyst_voices_brands`
/// package.
///
/// The [BrandChangedEvent] accepts a [BrandKey] a simple enum that
/// contains all possible brands/themes.
///
/// To trigger the theme change is just necessary to dispatch the
/// [BrandChangedEvent] with the appropriate key:
///
/// ```dart
/// context.read<BrandBloc>().add(
/// const BrandChangedEvent(BrandKey.catalyst),
/// );
/// ```
///
/// Usage example:
///
/// ```dart
/// BlocProvider(
/// create: (context) => BrandBloc(),
/// child: BlocBuilder<BrandBloc, BrandState>(
/// builder: (context, state) {
/// return MaterialApp(
/// home: Builder(
/// builder: (context) => Scaffold(
/// body: Row(
/// children: [
/// MaterialButton(
/// color: Theme.of(context).primaryColor,
/// onPressed: () {
/// context.read<BrandBloc>().add(
/// const BrandChangedEvent(BrandKey.catalyst),
/// );
/// },
/// child: const Text('Switch to Catalyst Theme'),
/// ),
/// ],
/// ),
/// ),
/// ),
/// theme: ThemeBuilder.buildTheme(state.brandKey),
/// );
/// },
/// ),
/// );
/// ```
final class BrandBloc extends Bloc<BrandEvent, BrandState> {
BrandBloc() : super(const BrandState()) {
on<BrandChangedEvent>(_onBrandChanged);
}

void _onBrandChanged(
BrandChangedEvent event,
Emitter<BrandState> emit,
) {
emit(BrandState(brandKey: event.brand));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
part of 'brand_bloc.dart';

sealed class BrandEvent extends Equatable {
const BrandEvent();

@override
List<Object> get props => [];
}

final class BrandChangedEvent extends BrandEvent {
final BrandKey brand;

const BrandChangedEvent(this.brand);

@override
List<Object> get props => [brand];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
part of 'brand_bloc.dart';

final class BrandState extends Equatable {
final BrandKey? brandKey;

const BrandState({BrandKey? brandKey})
: brandKey = brandKey ?? BrandKey.catalyst;

@override
List<Object> get props => [brandKey ?? ''];
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export 'authentication/authentication.dart';
export 'brand/brand.dart';
export 'login/login.dart';
5 changes: 5 additions & 0 deletions catalyst_voices/packages/catalyst_voices_blocs/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ environment:
dependencies:
bloc: ^8.1.2
bloc_concurrency: ^0.2.2
catalyst_voices_brands:
path: ../catalyst_voices_brands
catalyst_voices_models:
path: ../catalyst_voices_models
catalyst_voices_repositories:
Expand All @@ -30,4 +32,7 @@ dev_dependencies:
bloc_test: ^9.1.4
catalyst_analysis:
path: ../../../catalyst_voices_packages/catalyst_analysis
flutter_bloc: ^8.1.5
flutter_test:
sdk: flutter
test: ^1.24.9
44 changes: 44 additions & 0 deletions catalyst_voices/packages/catalyst_voices_brands/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# VSCode related
.vscode/*

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
pubspec.lock

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Test related
coverage
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Catalyst Voices Brands
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
include: package:catalyst_analysis/analysis_options.1.0.0.yaml

analyzer:
exclude: [
build/**,
lib/*.g.dart,
lib/generated/**
]

linter:
rules:
public_member_api_docs: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
library catalyst_voices_brands;

export 'src/catalyst_voices_brands.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// Simple Enum to store all possible Brands.
enum BrandKey {
catalyst,
fallback,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export 'brands/brands.dart';
export 'theme_builder/theme_builder.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:catalyst_voices_brands/src/brands/brands.dart';
import 'package:catalyst_voices_brands/src/themes/catalyst.dart';
import 'package:catalyst_voices_brands/src/themes/fallback.dart';
import 'package:flutter/material.dart';

/// A utility class to build themes dynamically based on brand keys.
///
/// [buildTheme] can be used to obtain the corresponding theme data for the
/// [BrandKey] passed to the method.
///
/// For each brand there is a specific key defined in the [BrandKey] enum
/// and a corresponding [ThemeData] in the `themes` folder.
///
/// [buildTheme] defaults to the [catalyst] theme.
class ThemeBuilder {
static ThemeData buildTheme(BrandKey? brandKey) {
switch (brandKey) {
case BrandKey.catalyst:
return catalyst;
case BrandKey.fallback:
return fallback;
case null:
return catalyst;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:catalyst_voices_assets/catalyst_voices_assets.dart';
import 'package:flutter/material.dart';

/// [ThemeData] for the `catalyst` brand.
final ThemeData catalyst = ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: VoicesColors.blue,
primary: VoicesColors.blue,
),
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import 'package:flutter/material.dart';

/// [ThemeData] for the `fallback` brand.
final ThemeData fallback = ThemeData(useMaterial3: true);
24 changes: 24 additions & 0 deletions catalyst_voices/packages/catalyst_voices_brands/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: catalyst_voices_brands
description: Catalyst Voices Brands.
version: 0.1.0+1
publish_to: none

environment:
sdk: ">=3.3.0 <4.0.0"
flutter: 3.19.5

dependencies:
catalyst_voices_assets:
path: ../catalyst_voices_assets
flutter:
sdk: flutter

dev_dependencies:
catalyst_analysis:
path: ../../../catalyst_voices_packages/catalyst_analysis
catalyst_voices_blocs:
path: ../catalyst_voices_blocs
flutter_bloc: ^8.1.5
flutter_test:
sdk: flutter
test: ^1.24.9
Loading
Loading