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
@@ -1,71 +1,73 @@
import 'package:bloc/bloc.dart';

import 'package:catalyst_voices_models/catalyst_voices_models.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 passed to the [MaterialApp] as a theme
// allowing to change the theme at runtime.
//
// The [BrandChanged] accepts a [BrandKey] and uses that is used for
// the selection of the related [ThemeData] defined in the [brands]
// map.
// To trigger the theme change is just necessary to dispatch the
// [BrandChanged] with the appropriate key:
//
// ```dart
// context.read<BrandBloc>().add(
// const BrandChanged(BrandKey.catalyst),
// );
// ```
//
// Usage example:
//
// ```dart
// BlocProvider(
// create: (context) => BrandBloc(),
// child: BlocBuilder<BrandBloc, BrandState>(
// builder: (context, state) {
// return MaterialApp(
// builder: (context, state) => Scaffold(
// body: Row(
// children: [
// MaterialButton(
// color: Theme.of(context).primaryColor,
// onPressed: () {
// context.read<BrandBloc>().add(
// const BrandChanged(BrandKey.catalyst),
// );
// },
// child: const Text('Switch to Catalyst Theme'),
// ),
// ],
// ),
// ),
// theme: state.themeData,
// );
// },
// ),
// );
// ```


/// [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(
/// builder: (context, state) => Scaffold(
coire1 marked this conversation as resolved.
Show resolved Hide resolved
/// 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(BrandState()) {
on<BrandChanged>(_onBrandChanged);
BrandBloc() : super(const BrandState()) {
on<BrandChangedEvent>(_onBrandChanged);
}

void _onBrandChanged(
BrandChanged event,
BrandChangedEvent event,
Emitter<BrandState> emit,
) {
emit(BrandState(themeData: brands[event.brand]));
emit(BrandState(brandKey: event.brand));
}

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

abstract final class BrandEvent extends Equatable {
sealed class BrandEvent extends Equatable {
const BrandEvent();

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

final class BrandChanged extends BrandEvent {
final class BrandChangedEvent extends BrandEvent {
final BrandKey brand;

const BrandChanged(this.brand);
const BrandChangedEvent(this.brand);

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

final class BrandState extends Equatable {
final ThemeData? themeData;
final BrandKey? brandKey;

BrandState({ThemeData? themeData})
: themeData = themeData ?? brands[BrandKey.catalyst];
const BrandState({BrandKey? brandKey})
: brandKey = brandKey ?? BrandKey.catalyst;

@override
List<Object> get props => [themeData ?? ''];
List<Object> get props => [brandKey ?? ''];
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export 'authentication/authentication.dart';
export 'brand/brand.dart';
export 'dependency/dependency.dart';
export 'login/login.dart';
4 changes: 2 additions & 2 deletions catalyst_voices/packages/catalyst_voices_blocs/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ environment:
dependencies:
bloc: ^8.1.2
bloc_concurrency: ^0.2.2
catalyst_voices_assets:
path: ../catalyst_voices_assets
catalyst_voices_brands:
path: ../catalyst_voices_brands
catalyst_voices_models:
path: ../catalyst_voices_models
catalyst_voices_repositories:
Expand Down
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,
dummy,
coire1 marked this conversation as resolved.
Show resolved Hide resolved
}
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/dummy.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.dummy:
return dummy;
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,9 @@
import 'package:flutter/material.dart';

/// [ThemeData] for the `dummy` brand.
final ThemeData dummy = ThemeData.from(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFFFF5722),
primary: const Color(0xFFFF5722),
),
);
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.2.6 <4.0.0"
coire1 marked this conversation as resolved.
Show resolved Hide resolved
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:catalyst_voices_assets/catalyst_voices_assets.dart';
import 'package:catalyst_voices_blocs/src/brand/brand_bloc.dart';
import 'package:catalyst_voices_models/catalyst_voices_models.dart';
import 'package:catalyst_voices_brands/catalyst_voices_brands.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
Expand All @@ -22,7 +22,7 @@ void main() {
color: Theme.of(context).primaryColor,
onPressed: () {
context.read<BrandBloc>().add(
const BrandChanged(BrandKey.catalyst),
const BrandChangedEvent(BrandKey.catalyst),
);
},
child: const Text('Catalyst'),
Expand All @@ -33,14 +33,14 @@ void main() {
child: const Text('Dummy'),
onPressed: () {
context.read<BrandBloc>().add(
const BrandChanged(BrandKey.dummy),
const BrandChangedEvent(BrandKey.dummy),
);
},
),
],
),
),
theme: state.themeData,
theme: ThemeBuilder.buildTheme(state.brandKey),
);
},
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
library catalyst_voices_models;

export 'src/authentication_status.dart';
export 'src/brands.dart';
export 'src/catalyst_voices_models.dart';
export 'src/session_data.dart';

This file was deleted.

Loading
Loading