initial commit (migrated)

This commit is contained in:
fiatcode 2025-10-20 16:43:59 +07:00
commit b594facb51
143 changed files with 11057 additions and 0 deletions

View file

@ -0,0 +1,37 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:kuwot/core/domain/no_params.dart';
import 'package:kuwot/core/presentation/bloc/error_state.dart';
import 'package:kuwot/features/quote/domain/entities/background_image.dart';
import 'package:kuwot/features/quote/domain/use_cases/get_background_images.dart';
part 'background_images_events.dart';
part 'background_images_states.dart';
class BackgroundImagesBloc
extends Bloc<BackgroundImagesEvent, BackgroundImagesState> {
final GetBackgroundImages getBackgroundImages;
BackgroundImagesBloc({required this.getBackgroundImages})
: super(const BackgroundImagesInitialState()) {
on<GetBackgroundImagesEvent>(_onGetBackgroundImages);
}
Future<void> _onGetBackgroundImages(
GetBackgroundImagesEvent event,
Emitter<BackgroundImagesState> emit,
) async {
emit(const BackgroundImagesLoadingState());
final result = await getBackgroundImages(const NoParams());
result.fold(
(failure) => emit(
BackgroundImagesErrorState(
message: failure.message,
cause: failure.cause,
),
),
(photos) => emit(BackgroundImagesLoadedState(photos)),
);
}
}

View file

@ -0,0 +1,12 @@
part of 'background_images_bloc.dart';
abstract class BackgroundImagesEvent extends Equatable {
const BackgroundImagesEvent();
}
class GetBackgroundImagesEvent extends BackgroundImagesEvent {
const GetBackgroundImagesEvent();
@override
List<Object> get props => [];
}

View file

@ -0,0 +1,45 @@
part of 'background_images_bloc.dart';
abstract class BackgroundImagesState extends Equatable {
const BackgroundImagesState();
@override
String toString() => runtimeType.toString();
}
class BackgroundImagesInitialState extends BackgroundImagesState {
const BackgroundImagesInitialState();
@override
List<Object> get props => [];
}
class BackgroundImagesLoadingState extends BackgroundImagesState {
const BackgroundImagesLoadingState();
@override
List<Object> get props => [];
}
class BackgroundImagesLoadedState extends BackgroundImagesState {
final List<BackgroundImage> backgroundImages;
const BackgroundImagesLoadedState(this.backgroundImages);
@override
List<Object> get props => [backgroundImages];
}
class BackgroundImagesErrorState extends BackgroundImagesState
implements ErrorState {
@override
final String message;
@override
final Exception? cause;
const BackgroundImagesErrorState({required this.message, this.cause});
@override
List<Object?> get props => [message, cause];
}

View file

@ -0,0 +1,83 @@
import 'package:bloc_concurrency/bloc_concurrency.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:kuwot/core/data/local/config.dart';
import 'package:kuwot/core/data/local/translation_target_config.dart';
import 'package:kuwot/core/presentation/bloc/error_state.dart';
import 'package:kuwot/features/quote/domain/entities/quote.dart';
import 'package:kuwot/features/quote/domain/use_cases/get_quote.dart';
import 'package:kuwot/features/quote/domain/use_cases/get_translated_quote.dart';
part 'quote_events.dart';
part 'quote_states.dart';
class QuoteBloc extends Bloc<QuoteEvent, QuoteState> {
final GetQuote getQuote;
final GetTranslatedQuote getTranslatedQuote;
final Config<TranslationTarget> translationTargetConfig;
int _originalQuoteId = -1;
QuoteBloc({
required this.getQuote,
required this.getTranslatedQuote,
required this.translationTargetConfig,
}) : super(const QuoteInitialState()) {
on<GetQuoteEvent>(_onGetQuoteEvent, transformer: droppable());
on<GetTranslatedQuoteEvent>(
_onGetTranslatedQuoteEvent,
transformer: droppable(),
);
}
Future<void> _onGetQuoteEvent(
QuoteEvent event,
Emitter<QuoteState> emit,
) async {
emit(const QuoteLoadingState());
// add delay to limit the number of api calls
await Future.delayed(const Duration(seconds: 1));
// check if need to translate the quote
final translationTarget = await translationTargetConfig.get();
// get quote
final result = await getQuote(GetQuoteParams(translationTarget));
result.fold((failure) => emit(QuoteErrorState(message: failure.message)), (
quote,
) {
_originalQuoteId = quote.id;
emit(QuoteLoadedState(quote: quote));
});
}
Future<void> _onGetTranslatedQuoteEvent(
GetTranslatedQuoteEvent event,
Emitter<QuoteState> emit,
) async {
emit(const QuoteLoadingState());
// add delay to limit the number of api calls
await Future.delayed(const Duration(seconds: 1));
// get translation target
final translationTarget = await translationTargetConfig.get();
if (translationTarget == null) {
emit(const QuoteErrorState(message: 'Translation target is not set'));
return;
}
// get translated quote
final result = await getTranslatedQuote(
GetTranslatedQuoteParams(
id: _originalQuoteId,
translationTarget: translationTarget,
),
);
result.fold(
(failure) => emit(QuoteErrorState(message: failure.message)),
(quote) => emit(QuoteLoadedState(quote: quote)),
);
}
}

View file

@ -0,0 +1,21 @@
part of 'quote_bloc.dart';
abstract class QuoteEvent extends Equatable {
const QuoteEvent();
}
class GetQuoteEvent extends QuoteEvent {
const GetQuoteEvent();
@override
List<Object> get props => [];
}
class GetTranslatedQuoteEvent extends QuoteEvent {
final TranslationTarget translationTarget;
const GetTranslatedQuoteEvent(this.translationTarget);
@override
List<Object> get props => [translationTarget];
}

View file

@ -0,0 +1,44 @@
part of 'quote_bloc.dart';
abstract class QuoteState extends Equatable {
const QuoteState();
@override
String toString() => runtimeType.toString();
}
class QuoteInitialState extends QuoteState {
const QuoteInitialState();
@override
List<Object> get props => [];
}
class QuoteLoadingState extends QuoteState {
const QuoteLoadingState();
@override
List<Object> get props => [];
}
class QuoteLoadedState extends QuoteState {
final Quote quote;
const QuoteLoadedState({required this.quote});
@override
List<Object> get props => [quote];
}
class QuoteErrorState extends QuoteState implements ErrorState {
@override
final String message;
@override
final Exception? cause;
const QuoteErrorState({required this.message, this.cause});
@override
List<Object?> get props => [message, cause];
}

View file

@ -0,0 +1,31 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:kuwot/core/domain/no_params.dart';
import 'package:kuwot/core/presentation/bloc/error_state.dart';
import 'package:kuwot/features/quote/domain/entities/translation.dart';
import 'package:kuwot/features/quote/domain/use_cases/get_translations.dart';
part 'translations_events.dart';
part 'translations_states.dart';
class TranslationsBloc extends Bloc<TranslationsEvent, TranslationsState> {
final GetTranslations getTranslations;
TranslationsBloc({required this.getTranslations})
: super(const TranslationsInitialState()) {
on<GetTranslationsEvent>(_onGetTranslationEvent);
}
Future<void> _onGetTranslationEvent(
TranslationsEvent event,
Emitter<TranslationsState> emit,
) async {
emit(const TranslationsLoadingState());
final translations = await getTranslations(const NoParams());
translations.fold(
(failure) => emit(TranslationsErrorState(message: failure.message)),
(translations) =>
emit(TranslationsLoadedState(translations: translations)),
);
}
}

View file

@ -0,0 +1,12 @@
part of 'translations_bloc.dart';
abstract class TranslationsEvent extends Equatable {
const TranslationsEvent();
}
class GetTranslationsEvent extends TranslationsEvent {
const GetTranslationsEvent();
@override
List<Object> get props => [];
}

View file

@ -0,0 +1,41 @@
part of 'translations_bloc.dart';
abstract class TranslationsState extends Equatable {
const TranslationsState();
}
class TranslationsInitialState extends TranslationsState {
const TranslationsInitialState();
@override
List<Object> get props => [];
}
class TranslationsLoadingState extends TranslationsState {
const TranslationsLoadingState();
@override
List<Object> get props => [];
}
class TranslationsLoadedState extends TranslationsState {
final List<Translation> translations;
const TranslationsLoadedState({required this.translations});
@override
List<Object> get props => [translations];
}
class TranslationsErrorState extends TranslationsState implements ErrorState {
@override
final String message;
@override
final Exception? cause;
const TranslationsErrorState({required this.message, this.cause});
@override
List<Object?> get props => [message, cause];
}