feature(collections): Заготовка под апи. Переключалка коллекций

This commit is contained in:
2025-09-08 16:39:33 +03:00
parent 285c4ca3f2
commit 8b546214eb
11 changed files with 142 additions and 1188 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -8,10 +8,6 @@ clean:
codegen: clean
fvm flutter pub run build_runner build --delete-conflicting-outputs
watchgen: clean
fvm flutter pub run build_runner watch --delete-conflicting-outputs
iosPod:
cd ios && rm -rf Podfile.lock Pods Runner.xcworkspace && fvm flutter clean && fvm flutter pub get && pod install
@@ -31,8 +27,8 @@ macosPodUpdate:
cd macos && pod install --repo-update
androidBuild: clean
fvm flutter build apk --split-per-abi
mv `pwd`/build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk /tmp/$(PROJECT_NAME)-$(env)-$(ver).apk
fvm flutter build apk
mv `pwd`/build/app/outputs/flutter-apk/app-release.apk /tmp/$(PROJECT_NAME)-$(env)-$(ver).apk
echo /tmp/$(PROJECT_NAME)-$(env)-$(ver).apk
open /tmp

View File

@@ -2,6 +2,8 @@
import 'package:dio/dio.dart';
import 'package:dio_smart_retry/dio_smart_retry.dart';
import 'package:remever/common/functions.dart';
import 'package:remever/common/resources.dart';
import 'package:remever/common/storage.dart';
import 'package:talker_dio_logger/talker_dio_logger_interceptor.dart';
import 'package:talker_dio_logger/talker_dio_logger_settings.dart';
@@ -17,17 +19,17 @@ InterceptorsWrapper get _auth {
RequestOptions options,
RequestInterceptorHandler handler,
) async {
// try {
// String? token = await authSecStorage.read(key: StorageKeys.authToken);
try {
String? token = await authSecStorage.read(key: StorageKeys.accessToken);
// if (token != null) {
// options.headers['Authorization'] = 'Bearer $token';
// }
// } catch (e) {
// getIt<LogService>().log(
// entity: LogEntity.error(message: 'Error to load access token $e'),
// );
// }
if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
}
} catch (e) {
// getIt<LogService>().log(
// entity: LogEntity.error(message: 'Error to load access token $e'),
// );
}
return handler.next(options);
},

View File

@@ -12,6 +12,8 @@ import 'package:remever/screens/collections/widgets/collection_card.dart';
import 'package:remever/screens/collections/widgets/collections_app_bar.dart';
import 'package:remever/screens/collections/widgets/collections_filters.dart';
import 'package:remever/services/collection/collections_interface.dart';
import 'package:remever/services/collection/collections_service.dart';
import 'package:remever/services/tickets/tickets_interface.dart';
@RoutePage()
class CollectionScreen extends StatefulWidget {

View File

@@ -1,12 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:remever/common/resources.dart';
import 'package:remever/common/widgets/typography.dart';
import 'package:remever/common/widgets/wspace.dart';
import 'package:remever/components/extensions/context.dart';
import 'package:remever/components/extensions/state.dart';
import 'package:remever/widgets/debug/app_debug.dart';
class CollectionsFilters extends StatefulWidget {
const CollectionsFilters({super.key});
@@ -16,37 +12,52 @@ class CollectionsFilters extends StatefulWidget {
}
class _CollectionsFiltersState extends State<CollectionsFilters> {
static const List<String> _filterOptions = ['Все', 'Публичные', 'Подписки'];
String _selected = 'Все';
void _onFilterSelected(String title) {
safeSetState(() {
_selected = title;
});
}
@override
Widget build(BuildContext context) {
return AppDebug(
builder: (context, isDebug) {
if (!isDebug) return HSpace(20);
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 28).r,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
_buildFilterButton(AppColors.white, 'Все', () {
safeSetState(() {});
}),
_buildFilterButton(AppColors.gray_bg, 'Публичные', () {
safeSetState(() {});
}),
_buildFilterButton(AppColors.gray_bg, 'Подписки', () {
safeSetState(() {});
}),
],
),
);
},
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 28).r,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: _buildFilterButtons(),
),
);
}
///
/// Построение кнопки фильтра
///
Widget _buildFilterButton(Color color, String title, void Function()? onTap) {
List<Widget> _buildFilterButtons() {
return _filterOptions
.map(
(title) => _FilterButton(
title: title,
isSelected: _selected == title,
onTap: () => _onFilterSelected(title),
),
)
.toList();
}
}
class _FilterButton extends StatelessWidget {
final String title;
final bool isSelected;
final VoidCallback onTap;
const _FilterButton({
required this.title,
required this.isSelected,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
@@ -54,7 +65,7 @@ class _CollectionsFiltersState extends State<CollectionsFilters> {
height: 36.h,
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(16)).r,
color: color,
color: isSelected ? AppColors.white : AppColors.bg,
),
child: Center(child: AppTypography(title, type: SemiBold14px())),
),

View File

@@ -5,6 +5,10 @@ import 'package:remever/models/crud_collection_dto.dart';
/// Интерфейс взаимодействия с коллекциями
///
abstract interface class CollectionsInterface {
/// работа с api
Future<void> getCollectionsFromApi();
Future<void> createCollectionApi();
/// Получение списка коллекций
Stream<List<Collection>> watchCollectionsList({String? search});

View File

@@ -1,4 +1,6 @@
import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';
import 'package:remever/common/services/api_client.dart';
import 'package:remever/database/database.dart';
import 'package:remever/inject.dart';
import 'package:remever/models/crud_collection_dto.dart';
@@ -35,4 +37,37 @@ final class CollectionsService implements CollectionsInterface {
// TODO: implement makeCollectionPublic
throw UnimplementedError();
}
@override
Future<void> getCollectionsFromApi() async {
try {
final Response<dynamic> response = await apiClient.get(
'/collections',
queryParameters: <String, dynamic>{'perPage': 20, 'page': 1},
);
print('data');
} catch (e) {
print('Response error $e');
}
}
@override
Future<void> createCollectionApi() async {
try {
final Response<dynamic> response = await apiClient.post(
'/collections',
data: {
"title": "Основы программирования для утюгов",
"description":
"Коллекция карточек по основам программирования для начинающих",
"is_public": true,
},
);
print('data');
} catch (e) {
print('Response error $e');
}
}
}

View File

@@ -5,6 +5,10 @@ import 'package:remever/models/create_ticket_dto.dart';
/// Интерфейс взаимодействия с билетами в коллекция
///
abstract interface class TicketsInterface {
/// работа с api
Future<void> getTicketsFromApi();
Future<void> createTicketApi();
/// Получение списка билетов
Stream<List<Ticket>> watchTicketsList(String collectionId);

View File

@@ -1,4 +1,6 @@
import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';
import 'package:remever/common/services/api_client.dart';
import 'package:remever/database/database.dart';
import 'package:remever/inject.dart';
import 'package:remever/models/create_ticket_dto.dart';
@@ -32,4 +34,40 @@ final class TicketsService implements TicketsInterface {
newCollectionId,
);
}
@override
Future<void> getTicketsFromApi() async {
try {
final Response<dynamic> response = await apiClient.get('/cards');
print('data');
} catch (e) {
print('Response error $e');
}
}
@override
Future<void> createTicketApi() async {
try {
final Response<dynamic> response = await apiClient.post(
'/cards',
data: {
"title": "Основы программирования",
"question":
"Коллекция карточек по основам программирования для начинающих",
"question_picture_id": 1,
"answer":
"Коллекция карточек по основам программирования для начинающих",
"answer_picture_id": 2,
"is_public": true,
"is_reverse": false,
"collection_id": 1,
},
);
print('data');
} catch (e) {
print('Response error $e');
}
}
}

View File

@@ -2,7 +2,7 @@ name: remever
description: ""
publish_to: 'none'
version: 1.0.0+7
version: 1.0.0+8
environment:
sdk: ^3.7.0