Browse Source

add: topic page

pull/12/head
AmirrezaChegini 7 days ago
parent
commit
0b505995d1
  1. 3
      assets/svg/icon_art.svg
  2. 3
      assets/svg/icon_random.svg
  3. 2
      lib/common_ui/resources/my_assets.dart
  4. 13
      lib/core/params/topic_params.dart
  5. 8
      lib/core/routers/my_routes.dart
  6. 4
      lib/features/battle_league/presentation/controller/battle_league_controller.dart
  7. 4
      lib/features/battle_league/presentation/ui/battle_league_page.dart
  8. 28
      lib/features/topic/data/datasource/topic_datasource.dart
  9. 13
      lib/features/topic/data/model/topic_model.dart
  10. 29
      lib/features/topic/data/repository_impl/topic_repository_impl.dart
  11. 14
      lib/features/topic/domain/entity/topic_entity.dart
  12. 8
      lib/features/topic/domain/repository/topic_repository.dart
  13. 19
      lib/features/topic/domain/usecases/get_topic_usecase.dart
  14. 20
      lib/features/topic/presentation/binding/topic_binding.dart
  15. 54
      lib/features/topic/presentation/controller/topic_controller.dart
  16. 110
      lib/features/topic/presentation/ui/topic_page.dart
  17. 57
      lib/features/topic/presentation/ui/widgets/battle_grey_button.dart
  18. 64
      lib/features/topic/presentation/ui/widgets/topic_widget.dart
  19. 9
      lib/init_bindings.dart
  20. 9
      lib/l10n/app_en.arb
  21. 42
      lib/l10n/app_localizations.dart
  22. 21
      lib/l10n/app_localizations_en.dart

3
assets/svg/icon_art.svg

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.5 12C17.1022 12 16.7206 11.842 16.4393 11.5607C16.158 11.2794 16 10.8978 16 10.5C16 10.1022 16.158 9.72064 16.4393 9.43934C16.7206 9.15804 17.1022 9 17.5 9C17.8978 9 18.2794 9.15804 18.5607 9.43934C18.842 9.72064 19 10.1022 19 10.5C19 10.8978 18.842 11.2794 18.5607 11.5607C18.2794 11.842 17.8978 12 17.5 12ZM14.5 8C14.1022 8 13.7206 7.84196 13.4393 7.56066C13.158 7.27936 13 6.89782 13 6.5C13 6.10218 13.158 5.72064 13.4393 5.43934C13.7206 5.15804 14.1022 5 14.5 5C14.8978 5 15.2794 5.15804 15.5607 5.43934C15.842 5.72064 16 6.10218 16 6.5C16 6.89782 15.842 7.27936 15.5607 7.56066C15.2794 7.84196 14.8978 8 14.5 8ZM9.5 8C9.10218 8 8.72064 7.84196 8.43934 7.56066C8.15804 7.27936 8 6.89782 8 6.5C8 6.10218 8.15804 5.72064 8.43934 5.43934C8.72064 5.15804 9.10218 5 9.5 5C9.89782 5 10.2794 5.15804 10.5607 5.43934C10.842 5.72064 11 6.10218 11 6.5C11 6.89782 10.842 7.27936 10.5607 7.56066C10.2794 7.84196 9.89782 8 9.5 8ZM6.5 12C6.10218 12 5.72064 11.842 5.43934 11.5607C5.15804 11.2794 5 10.8978 5 10.5C5 10.1022 5.15804 9.72064 5.43934 9.43934C5.72064 9.15804 6.10218 9 6.5 9C6.89782 9 7.27936 9.15804 7.56066 9.43934C7.84196 9.72064 8 10.1022 8 10.5C8 10.8978 7.84196 11.2794 7.56066 11.5607C7.27936 11.842 6.89782 12 6.5 12ZM12 3C9.61305 3 7.32387 3.94821 5.63604 5.63604C3.94821 7.32387 3 9.61305 3 12C3 14.3869 3.94821 16.6761 5.63604 18.364C7.32387 20.0518 9.61305 21 12 21C12.3978 21 12.7794 20.842 13.0607 20.5607C13.342 20.2794 13.5 19.8978 13.5 19.5C13.5 19.11 13.35 18.76 13.11 18.5C12.88 18.23 12.73 17.88 12.73 17.5C12.73 17.1022 12.888 16.7206 13.1693 16.4393C13.4506 16.158 13.8322 16 14.23 16H16C17.3261 16 18.5979 15.4732 19.5355 14.5355C20.4732 13.5979 21 12.3261 21 11C21 6.58 16.97 3 12 3Z" fill="white"/>
</svg>

3
assets/svg/icon_random.svg

@ -0,0 +1,3 @@
<svg width="16" height="19" viewBox="0 0 16 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.98752 0C7.72755 0 7.46753 0.0632144 7.26615 0.189643L0.836157 4.2255C0.433317 4.47836 0.433317 4.8782 0.836157 5.13105L7.26615 9.16691C7.66899 9.41977 8.306 9.41977 8.7088 9.16691L15.1388 5.13105C15.5416 4.87824 15.5416 4.47835 15.1388 4.22554L8.7088 0.189689C8.50738 0.0631687 8.24745 0 7.98752 0ZM7.95283 2.42581C8.33224 2.43025 8.67334 2.52453 8.97614 2.70863C9.18324 2.83457 9.31887 2.97826 9.38302 3.13971C9.44504 3.29991 9.44869 3.511 9.39397 3.77299L9.32662 4.03362C9.282 4.22012 9.27273 4.35426 9.29883 4.43601C9.3228 4.51655 9.38232 4.58574 9.4774 4.64356L9.6201 4.73025L8.2211 5.58073L8.06565 5.48631C7.89233 5.38099 7.78172 5.26193 7.73382 5.12913C7.68381 4.99509 7.69214 4.78187 7.75882 4.48945L7.82297 4.22691C7.8603 4.07055 7.86394 3.94239 7.83392 3.84242C7.80642 3.74084 7.74406 3.6605 7.64685 3.60139C7.49888 3.51144 7.32166 3.47912 7.1152 3.50442C6.90661 3.52848 6.69123 3.60803 6.46906 3.74308C6.2598 3.8703 6.06967 4.02955 5.89868 4.22084C5.72562 4.41094 5.57707 4.62847 5.45303 4.87345L4.45751 4.26816C4.68137 4.02425 4.90132 3.8109 5.11738 3.62811C5.33346 3.44541 5.56164 3.28098 5.80191 3.13482C6.43231 2.75158 7.01854 2.5237 7.5606 2.4512C7.69069 2.43312 7.82177 2.42462 7.95292 2.42576L7.95283 2.42581ZM10.0894 5.01559L11.2182 5.70181L9.81916 6.55228L8.69036 5.8661L10.0894 5.01559ZM0.406797 5.89556C0.16463 5.88848 0 6.09361 0 6.45645V13.6592C0 14.164 0.318652 14.7629 0.721493 15.0153L6.90637 18.8908C7.30922 19.1432 7.62787 18.9436 7.62787 18.4388V11.2359C7.62787 10.7311 7.30922 10.1324 6.90637 9.8799L0.721493 6.0045C0.60826 5.93347 0.501551 5.89821 0.406797 5.89547V5.89556ZM15.5932 5.89565C15.4985 5.8984 15.3919 5.93357 15.2786 6.00459L9.0935 9.87999C8.69066 10.1324 8.37201 10.7313 8.37201 11.2361V18.4391C8.37201 18.9438 8.69066 19.1433 9.0935 18.8908L15.2786 15.0155C15.6815 14.7631 16 14.1643 16 13.6595V6.45655C16 6.09379 15.8354 5.88871 15.5932 5.89575V5.89565ZM2.05806 8.80754C2.33392 8.86996 2.58584 8.94628 2.81382 9.0365C3.04236 9.12704 3.26321 9.23898 3.47386 9.37108C4.03006 9.71958 4.45406 10.1167 4.74585 10.5624C5.03765 11.0054 5.18355 11.478 5.18355 11.9801C5.18355 12.2377 5.1391 12.4412 5.05019 12.5905C4.96126 12.7372 4.80967 12.8605 4.59541 12.9602L4.37652 13.0479C4.2215 13.1138 4.12006 13.1817 4.07218 13.2516C4.02433 13.3188 4.00041 13.4116 4.00041 13.5299V13.7073L2.766 12.9339V12.7407C2.76597 12.5251 2.80358 12.3581 2.87881 12.2397C2.95405 12.1186 3.11249 12.0049 3.35414 11.8986L3.57303 11.807C3.70296 11.7517 3.79756 11.6822 3.85683 11.5984C3.91831 11.516 3.94907 11.4144 3.9491 11.2934C3.9491 11.1095 3.89438 10.932 3.78493 10.7609C3.67551 10.5872 3.52278 10.4389 3.32674 10.316C3.14208 10.2004 2.9426 10.1201 2.72829 10.0752C2.514 10.0277 2.29059 10.0179 2.05806 10.0457V8.80754ZM13.4041 9.20066C13.4681 9.20066 13.5275 9.20817 13.5822 9.22318C13.874 9.30061 14.0199 9.59041 14.0199 10.0926C14.0199 10.3502 13.9755 10.6093 13.8866 10.8701C13.7977 11.1282 13.6461 11.4413 13.4318 11.8095L13.2129 12.1715C13.0579 12.4316 12.9564 12.6266 12.9086 12.7564C12.8607 12.8836 12.8368 13.0064 12.8368 13.1247V13.3022L11.6024 14.0755V13.8823C11.6024 13.6667 11.64 13.4526 11.7152 13.2398C11.7905 13.0244 11.9489 12.7123 12.1905 12.3033L12.4094 11.9374C12.5393 11.7193 12.6339 11.5312 12.6932 11.3732C12.7547 11.2137 12.7855 11.0734 12.7855 10.9525C12.7855 10.7685 12.7308 10.6595 12.6214 10.6255C12.512 10.589 12.3592 10.6321 12.1631 10.7548C11.9785 10.8705 11.779 11.0402 11.5648 11.2639C11.3505 11.4849 11.1271 11.755 10.8945 12.0741V10.8359C11.1704 10.5527 11.4223 10.3134 11.6501 10.118C11.8782 9.92256 12.0982 9.75848 12.3102 9.62572C12.7621 9.34253 13.1268 9.20083 13.4042 9.20062L13.4041 9.20066ZM2.76596 13.5176L4.00041 14.2909V15.6948L2.766 14.9215V13.5177L2.76596 13.5176ZM12.8368 13.8858V15.2896L11.6024 16.0629V14.6592L12.8368 13.8858Z" fill="#DCEEFA"/>
</svg>

2
lib/common_ui/resources/my_assets.dart

@ -62,6 +62,8 @@ class MyAssets {
static const String iconDiamond = 'assets/svg/icon_diamond.svg';
static const String mic = 'assets/svg/mic.svg';
static const String micBLur = 'assets/svg/mic_blur.svg';
static const String iconArt = 'assets/svg/icon_art.svg';
static const String iconRandom = 'assets/svg/icon_random.svg';
/// ----- Audios -----
static const String sampleAudio = 'assets/audios/sample.mp3';

13
lib/core/params/topic_params.dart

@ -0,0 +1,13 @@
class TopicParams {
int? id;
TopicParams({this.id});
TopicParams copyWith({
int? id,
}) {
return TopicParams(
id: id ?? this.id,
);
}
}

8
lib/core/routers/my_routes.dart

@ -15,6 +15,8 @@ import 'package:shia_game_flutter/features/battle_league/presentation/ui/battle_
import 'package:get/get.dart';
import 'package:shia_game_flutter/features/shop/presentation/binding/shop_binding.dart';
import 'package:shia_game_flutter/features/shop/presentation/ui/shop_page.dart';
import 'package:shia_game_flutter/features/topic/presentation/binding/topic_binding.dart';
import 'package:shia_game_flutter/features/topic/presentation/ui/topic_page.dart';
class Routes {
static const Routes _i = Routes._internal();
@ -29,6 +31,7 @@ class Routes {
static const String awardsPage = '/awards_page';
static const String profilePage = '/profile_page';
static const String battleLeaguePage = '/battle_league_page';
static const String topicPage = '/topic_page';
}
final List<GetPage> appPages = [
@ -74,4 +77,9 @@ final List<GetPage> appPages = [
page: () => const BattleLeaguePage(),
binding: BattleLeagueBinding(),
),
GetPage(
name: Routes.topicPage,
page: () => const TopicPage(),
binding: TopicBinding(),
),
];

4
lib/features/battle_league/presentation/controller/battle_league_controller.dart

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:shia_game_flutter/core/params/sample_params.dart';
import 'package:shia_game_flutter/core/routers/my_routes.dart';
import 'package:shia_game_flutter/core/status/base_status.dart';
import 'package:shia_game_flutter/features/battle_league/domain/entity/battle_league_entity.dart';
import 'package:shia_game_flutter/features/battle_league/domain/usecases/get_battle_league_usecase.dart';
@ -38,6 +39,9 @@ class BattleLeagueController extends GetxController
final Rx<BaseStatus> getBattleLeagueStatus = Rx(const BaseInit());
/// ------ Functions ------
void goToTopicPage(){
Get.toNamed(Routes.topicPage);
}
/// ------ Api Calls ------
Future<void> getBattleLeague() async {

4
lib/features/battle_league/presentation/ui/battle_league_page.dart

@ -33,7 +33,7 @@ class BattleLeaguePage extends GetView<BattleLeagueController> {
_tabBars(context),
12.h.gapHeight,
_tabViews(),
56.0.gapHeight,
56.h.gapHeight,
_startButton(context),
],
),
@ -77,7 +77,7 @@ class BattleLeaguePage extends GetView<BattleLeagueController> {
padding: const EdgeInsets.symmetric(horizontal: 30),
child: BattleLeagueStartButton(
title: context.translate.play_now,
onTap: () {},
onTap: controller.goToTopicPage,
),
);
}

28
lib/features/topic/data/datasource/topic_datasource.dart

@ -0,0 +1,28 @@
import 'package:shia_game_flutter/core/constants/my_api.dart';
import 'package:shia_game_flutter/core/network/http_request.dart';
import 'package:shia_game_flutter/core/params/topic_params.dart';
import 'package:shia_game_flutter/core/response/base_response.dart';
import 'package:shia_game_flutter/features/topic/data/model/topic_model.dart';
import 'package:shia_game_flutter/features/topic/domain/entity/topic_entity.dart';
abstract class ITopicDatasource {
Future<TopicEntity> getData({required TopicParams params});
}
class TopicDatasourceImpl implements ITopicDatasource {
final IHttpRequest httpRequest;
const TopicDatasourceImpl(this.httpRequest);
@override
Future<TopicEntity> getData({required TopicParams params}) async {
final response = await httpRequest.get(
path: MyApi.baseUrl,
);
return BaseResponse.getData<TopicEntity>(
response?['data'],
(json) => TopicModel.fromJson(json),
);
}
}

13
lib/features/topic/data/model/topic_model.dart

@ -0,0 +1,13 @@
import 'package:shia_game_flutter/features/topic/domain/entity/topic_entity.dart';
class TopicModel extends TopicEntity {
const TopicModel({
super.id,
});
factory TopicModel.fromJson(Map<String, dynamic> json) {
return TopicModel(
id: json['id'],
);
}
}

29
lib/features/topic/data/repository_impl/topic_repository_impl.dart

@ -0,0 +1,29 @@
import 'package:flutter/foundation.dart';
import 'package:shia_game_flutter/core/error_handler/my_exception.dart';
import 'package:shia_game_flutter/core/params/topic_params.dart';
import 'package:shia_game_flutter/core/utils/data_state.dart';
import 'package:shia_game_flutter/features/topic/data/datasource/topic_datasource.dart';
import 'package:shia_game_flutter/features/topic/domain/entity/topic_entity.dart';
import 'package:shia_game_flutter/features/topic/domain/repository/topic_repository.dart';
class TopicRepositoryImpl implements ITopicRepository {
final ITopicDatasource datasource;
const TopicRepositoryImpl(this.datasource);
@override
Future<DataState<TopicEntity, MyException>> getData({required TopicParams params}) async {
try {
final TopicEntity response = await datasource.getData(params: params);
return DataState.success(response);
} on MyException catch (e) {
return DataState.error(e);
} catch (e) {
if (kDebugMode) {
rethrow;
} else {
return DataState.error(MyException(errorMessage: '$e'));
}
}
}
}

14
lib/features/topic/domain/entity/topic_entity.dart

@ -0,0 +1,14 @@
import 'package:equatable/equatable.dart';
class TopicEntity extends Equatable {
final int? id;
const TopicEntity({
this.id,
});
@override
List<Object?> get props => [
id,
];
}

8
lib/features/topic/domain/repository/topic_repository.dart

@ -0,0 +1,8 @@
import 'package:shia_game_flutter/core/error_handler/my_exception.dart';
import 'package:shia_game_flutter/core/params/topic_params.dart';
import 'package:shia_game_flutter/core/utils/data_state.dart';
import 'package:shia_game_flutter/features/topic/domain/entity/topic_entity.dart';
abstract class ITopicRepository {
Future<DataState<TopicEntity, MyException>> getData({required TopicParams params});
}

19
lib/features/topic/domain/usecases/get_topic_usecase.dart

@ -0,0 +1,19 @@
import 'package:shia_game_flutter/core/error_handler/my_exception.dart';
import 'package:shia_game_flutter/core/params/topic_params.dart';
import 'package:shia_game_flutter/core/usecase/usecase.dart';
import 'package:shia_game_flutter/core/utils/data_state.dart';
import 'package:shia_game_flutter/features/topic/domain/entity/topic_entity.dart';
import 'package:shia_game_flutter/features/topic/domain/repository/topic_repository.dart';
class GetTopicUseCase implements UseCase<TopicEntity, TopicParams> {
final ITopicRepository repository;
const GetTopicUseCase(this.repository);
@override
Future<DataState<TopicEntity, MyException>> call(TopicParams params) {
return repository.getData(params: params);
}
}

20
lib/features/topic/presentation/binding/topic_binding.dart

@ -0,0 +1,20 @@
import 'package:shia_game_flutter/features/topic/presentation/controller/topic_controller.dart';
import 'package:get/get.dart';
class TopicBinding extends Bindings {
@override
void dependencies() {
Get.put<TopicController>(TopicController(Get.find()));
}
Future<void> deleteBindings() async {
await Future.wait([
Get.delete<TopicController>(),
]);
}
Future<void> refreshBinding() async {
await deleteBindings();
dependencies();
}
}

54
lib/features/topic/presentation/controller/topic_controller.dart

@ -0,0 +1,54 @@
import 'package:flutter/cupertino.dart';
import 'package:shia_game_flutter/core/params/topic_params.dart';
import 'package:shia_game_flutter/core/status/base_status.dart';
import 'package:shia_game_flutter/features/topic/domain/entity/topic_entity.dart';
import 'package:shia_game_flutter/features/topic/domain/usecases/get_topic_usecase.dart';
import 'package:get/get.dart';
class TopicController extends GetxController with StateMixin {
/// ----- Constructor -----
TopicController(this.getTopicUseCase);
@override
void onInit() {
super.onInit();
change('', status: RxStatus.success());
}
@override
void onClose() {
textEditingController.dispose();
super.onClose();
}
/// ----- UseCases -----
final GetTopicUseCase getTopicUseCase;
/// ----- Variables -----
final Rx<TopicParams> topicParams = Rx(TopicParams());
final Rx<TopicEntity> topicEntity = Rx(const TopicEntity());
/// ------ Controllers ------
final TextEditingController textEditingController = TextEditingController();
/// ------ Statuses ------
final Rx<BaseStatus> getTopicStatus = Rx(const BaseInit());
/// ------ Functions ------
/// ------ Api Calls ------
Future<void> getTopic() async {
change('', status: RxStatus.loading());
await getTopicUseCase(topicParams.value).then(
(value) => value.fold(
(data) {
topicEntity.value = data;
change('', status: RxStatus.success());
},
(error) {
change('', status: RxStatus.error(error.errorMessage));
},
),
);
}
}

110
lib/features/topic/presentation/ui/topic_page.dart

@ -0,0 +1,110 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:shia_game_flutter/common_ui/resources/my_assets.dart';
import 'package:shia_game_flutter/common_ui/resources/my_colors.dart';
import 'package:shia_game_flutter/common_ui/resources/my_text_style.dart';
import 'package:shia_game_flutter/core/utils/gap.dart';
import 'package:shia_game_flutter/core/utils/my_localization.dart';
import 'package:shia_game_flutter/core/utils/screen_size.dart';
import 'package:shia_game_flutter/core/widgets/app_bar/enums/app_bar_type.dart';
import 'package:shia_game_flutter/core/widgets/app_bar/my_app_bar.dart';
import 'package:shia_game_flutter/features/battle_league/presentation/ui/widgets/battle_league_start_button.dart';
import 'package:shia_game_flutter/features/topic/presentation/controller/topic_controller.dart';
import 'package:shia_game_flutter/features/topic/presentation/ui/widgets/battle_grey_button.dart';
import 'package:shia_game_flutter/features/topic/presentation/ui/widgets/topic_widget.dart';
class TopicPage extends GetView<TopicController> {
const TopicPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: MyColors.battleLeagueBackgroundColor,
appBar: MyAppBar(
backgroundColor: MyColors.transparent,
type: AppBarType.battleLeague,
title: context.translate.choose_3_topics,
),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
20.h.gapHeight,
_title(context),
27.h.gapHeight,
_topicList(context),
20.h.gapHeight,
_randomButton(context),
const Spacer(),
_startButton(context),
],
),
),
);
}
Text _title(BuildContext context) {
return Text.rich(
TextSpan(
text: '${context.translate.choose} ',
style: Lexend.regular.copyWith(fontSize: 12.sp),
children: [
TextSpan(
text: '${context.translate.three_topics} ',
style: Lexend.regular.copyWith(
fontSize: 12.sp,
color: const Color(0xFF9858FF),
),
),
TextSpan(text: '${context.translate.or} '),
TextSpan(
text: '${context.translate.random.toLowerCase()} ',
style: Lexend.regular.copyWith(
fontSize: 12.sp,
color: const Color(0xFF9858FF),
),
),
TextSpan(text: context.translate.selection_option),
],
),
);
}
SizedBox _topicList(BuildContext context) {
return SizedBox(
width: context.widthScreen,
child: Wrap(
spacing: 20,
runSpacing: 14,
direction: Axis.horizontal,
alignment: WrapAlignment.center,
children: List.generate(
10,
(index) => TopicWidget(
label: context.translate.art,
image: MyAssets.iconArt,
onTap: () {},
),
),
),
);
}
Padding _randomButton(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: BattleGreyButton(
label: context.translate.random,
image: MyAssets.iconRandom,
onTap: () {},
),
);
}
Widget _startButton(BuildContext context) {
return const Padding(
padding: EdgeInsets.symmetric(horizontal: 30),
child: BattleLeagueStartButton(title: 'Start Finding'),
);
}
}

57
lib/features/topic/presentation/ui/widgets/battle_grey_button.dart

@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:shia_game_flutter/common_ui/resources/my_text_style.dart';
import 'package:shia_game_flutter/core/utils/screen_size.dart';
import 'package:shia_game_flutter/core/widgets/container/my_container.dart';
import 'package:shia_game_flutter/core/widgets/image/my_image.dart';
class BattleGreyButton extends StatelessWidget {
const BattleGreyButton({
super.key,
this.onTap,
this.label,
this.image,
});
final VoidCallback? onTap;
final String? label;
final String? image;
@override
Widget build(BuildContext context) {
return MyContainer(
onTap: onTap,
height: 48.h,
width: context.widthScreen,
borderRadius: const BorderRadius.all(Radius.circular(12)),
borderColor: const Color(0XFF8C9FAC),
gradient: const RadialGradient(
center: Alignment.center,
radius: 4.5,
colors: [
Color(0XFF8296A4),
Color(0XFF51636E),
],
),
boxShadow: [
BoxShadow(
offset: const Offset(0, 3.53),
blurRadius: 15.02,
color: const Color(0XFF94A3B8).withValues(alpha: 0.05),
),
],
child: Row(
mainAxisSize: MainAxisSize.min,
spacing: 6,
children: [
MyImage(
asset: image ?? '',
),
Text(
label ?? '',
style: Lexend.medium.copyWith(fontSize: 12.sp),
),
],
),
);
}
}

64
lib/features/topic/presentation/ui/widgets/topic_widget.dart

@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:shia_game_flutter/common_ui/resources/my_text_style.dart';
import 'package:shia_game_flutter/core/utils/screen_size.dart';
import 'package:shia_game_flutter/core/widgets/container/my_container.dart';
import 'package:shia_game_flutter/core/widgets/image/my_image.dart';
class TopicWidget extends StatelessWidget {
const TopicWidget({
super.key,
this.onTap,
this.label,
this.image,
});
final VoidCallback? onTap;
final String? label;
final String? image;
@override
Widget build(BuildContext context) {
return MyContainer(
onTap: onTap,
height: 48.h,
width: 148.w,
borderRadius: const BorderRadius.all(Radius.circular(12)),
borderGradient: LinearGradient(
begin: AlignmentDirectional.centerStart,
end: AlignmentDirectional.centerEnd,
colors: [
const Color(0XFFAA76FF),
const Color(0XFFAA76FF).withValues(alpha: 0),
],
),
gradient: const RadialGradient(
center: Alignment.center,
radius: 3,
colors: [
Color(0XFF9858FF),
Color(0XFF792BF3),
],
),
boxShadow: [
BoxShadow(
offset: const Offset(0, 3.53),
blurRadius: 15.02,
color: const Color(0XFF94A3B8).withValues(alpha: 0.05),
),
],
child: Row(
mainAxisSize: MainAxisSize.min,
spacing: 4,
children: [
MyImage(
asset: image ?? '',
),
Text(
label ?? '',
style: Lexend.medium.copyWith(fontSize: 12.sp),
),
],
),
);
}
}

9
lib/init_bindings.dart

@ -33,6 +33,10 @@ import 'package:shia_game_flutter/features/shop/data/datasource/shop_datasource.
import 'package:shia_game_flutter/features/shop/data/repository_impl/shop_repository_impl.dart';
import 'package:shia_game_flutter/features/shop/domain/repository/shop_repository.dart';
import 'package:shia_game_flutter/features/shop/domain/usecases/get_shop_usecase.dart';
import 'package:shia_game_flutter/features/topic/data/datasource/topic_datasource.dart';
import 'package:shia_game_flutter/features/topic/data/repository_impl/topic_repository_impl.dart';
import 'package:shia_game_flutter/features/topic/domain/repository/topic_repository.dart';
import 'package:shia_game_flutter/features/topic/domain/usecases/get_topic_usecase.dart';
void initBindings() {
/// ----- Classes -----
@ -77,4 +81,9 @@ void initBindings() {
Get.lazyPut<IBattleLeagueDatasource>(() => BattleLeagueDatasourceImpl(Get.find()), fenix: true);
Get.lazyPut<IBattleLeagueRepository>(() => BattleLeagueRepositoryImpl(Get.find()), fenix: true);
Get.lazyPut<GetBattleLeagueUseCase>(() => GetBattleLeagueUseCase(Get.find()), fenix: true);
/// ----- Topic Feature -----
Get.lazyPut<ITopicDatasource>(() => TopicDatasourceImpl(Get.find()), fenix: true);
Get.lazyPut<ITopicRepository>(() => TopicRepositoryImpl(Get.find()), fenix: true);
Get.lazyPut<GetTopicUseCase>(() => GetTopicUseCase(Get.find()), fenix: true);
}

9
lib/l10n/app_en.arb

@ -36,5 +36,12 @@
"play_now": "Play Now",
"country": "Country",
"city": "City",
"region": "Region"
"region": "Region",
"choose_3_topics": "Choose 3 topics",
"choose": "Choose",
"three_topics": "3 topics",
"or": "or",
"random": "Random",
"selection_option": "selection option",
"art": "Art"
}

42
lib/l10n/app_localizations.dart

@ -315,6 +315,48 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Region'**
String get region;
/// No description provided for @choose_3_topics.
///
/// In en, this message translates to:
/// **'Choose 3 topics'**
String get choose_3_topics;
/// No description provided for @choose.
///
/// In en, this message translates to:
/// **'Choose'**
String get choose;
/// No description provided for @three_topics.
///
/// In en, this message translates to:
/// **'3 topics'**
String get three_topics;
/// No description provided for @or.
///
/// In en, this message translates to:
/// **'or'**
String get or;
/// No description provided for @random.
///
/// In en, this message translates to:
/// **'Random'**
String get random;
/// No description provided for @selection_option.
///
/// In en, this message translates to:
/// **'selection option'**
String get selection_option;
/// No description provided for @art.
///
/// In en, this message translates to:
/// **'Art'**
String get art;
}
class _AppLocalizationsDelegate

21
lib/l10n/app_localizations_en.dart

@ -118,4 +118,25 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get region => 'Region';
@override
String get choose_3_topics => 'Choose 3 topics';
@override
String get choose => 'Choose';
@override
String get three_topics => '3 topics';
@override
String get or => 'or';
@override
String get random => 'Random';
@override
String get selection_option => 'selection option';
@override
String get art => 'Art';
}
Loading…
Cancel
Save