[data] migrate to bloc management
This commit is contained in:
parent
ecb537bf12
commit
c25256b13b
|
|
@ -0,0 +1,31 @@
|
||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:notube/services/download.dart';
|
||||||
|
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
part 'dl_form_state.dart';
|
||||||
|
|
||||||
|
class DlFormCubit extends Cubit<DlFormState> {
|
||||||
|
DlFormCubit() : super(DlFormInitial());
|
||||||
|
|
||||||
|
late DLServices dlService;
|
||||||
|
|
||||||
|
void setFormat(String newFormat) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
format: newFormat,
|
||||||
|
));
|
||||||
|
print(newFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUrl(String newUrl) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
url: newUrl,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
void download() async {
|
||||||
|
dlService = await DLServices.init();
|
||||||
|
await dlService.analyseUrl(state.url!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
part of 'dl_form_cubit.dart';
|
||||||
|
|
||||||
|
class DlFormState extends Equatable {
|
||||||
|
const DlFormState({
|
||||||
|
this.url = '',
|
||||||
|
this.format = 'MP3',
|
||||||
|
});
|
||||||
|
|
||||||
|
final String url;
|
||||||
|
final String format;
|
||||||
|
|
||||||
|
DlFormState copyWith({
|
||||||
|
String? url,
|
||||||
|
String? format,
|
||||||
|
}) {
|
||||||
|
return DlFormState(
|
||||||
|
url: url ?? this.url,
|
||||||
|
format: format ?? this.format,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [url, format];
|
||||||
|
}
|
||||||
|
|
||||||
|
final class DlFormInitial extends DlFormState {
|
||||||
|
const DlFormInitial();
|
||||||
|
}
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:notube/components/formComponents/formatDropdown.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:notube/components/formComponents/submitButton.dart';
|
import 'package:notube/dlForm/cubit/dl_form_cubit.dart';
|
||||||
import 'package:notube/components/formComponents/urlTextField.dart';
|
import 'package:notube/dlForm/formComponents/formatDropdown.dart';
|
||||||
import 'package:notube/states/dlFormState.dart';
|
import 'package:notube/dlForm/formComponents/submitButton.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:notube/dlForm/formComponents/urlTextField.dart';
|
||||||
|
|
||||||
class DlForm extends StatelessWidget {
|
class DlForm extends StatelessWidget {
|
||||||
const DlForm({super.key});
|
const DlForm({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ChangeNotifierProvider(
|
return BlocProvider(
|
||||||
create: (context) => DlFormState(),
|
create: (context) => DlFormCubit(),
|
||||||
child: Form(child: LayoutBuilder(
|
child: Form(child: LayoutBuilder(
|
||||||
builder: (BuildContext context, BoxConstraints constraints) {
|
builder: (BuildContext context, BoxConstraints constraints) {
|
||||||
if (constraints.maxWidth < 320) {
|
if (constraints.maxWidth < 320) {
|
||||||
|
|
@ -63,13 +63,16 @@ class DebugDlFormState extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var dlForm = context.watch<DlFormState>();
|
return BlocBuilder<DlFormCubit, DlFormState>(builder: (context, state) {
|
||||||
|
final url = state.url;
|
||||||
|
final format = state.format;
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text('Url: ${dlForm.url}'),
|
Text('Url: ${url}'),
|
||||||
Text('Format: ${dlForm.format}'),
|
Text('Format: ${format}'),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:notube/constants.dart';
|
import 'package:notube/constants.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:notube/dlForm/cubit/dl_form_cubit.dart';
|
||||||
import 'package:notube/states/dlFormState.dart';
|
|
||||||
|
|
||||||
const List<String> formatList = <String>[
|
const List<String> formatList = <String>[
|
||||||
"MP3",
|
"MP3",
|
||||||
|
|
@ -19,7 +19,7 @@ class DropdownFormat extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var dlForm = context.watch<DlFormState>();
|
final dlFormState = context.select((DlFormCubit cubit) => cubit.state);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
|
|
@ -29,12 +29,12 @@ class DropdownFormat extends StatelessWidget {
|
||||||
|
|
||||||
// dropdown below..
|
// dropdown below..
|
||||||
child: DropdownButton<String>(
|
child: DropdownButton<String>(
|
||||||
value: dlForm.format,
|
value: dlFormState.format,
|
||||||
elevation: 16,
|
elevation: 16,
|
||||||
style: const TextStyle(color: colorMainWhite),
|
style: const TextStyle(color: colorMainWhite),
|
||||||
dropdownColor: colorMainBlue,
|
dropdownColor: colorMainBlue,
|
||||||
onChanged: (String? value) {
|
onChanged: (String? value) {
|
||||||
dlForm.setFormat(value!);
|
context.read<DlFormCubit>().setFormat(value!);
|
||||||
},
|
},
|
||||||
underline: Container(),
|
underline: Container(),
|
||||||
items: formatList.map<DropdownMenuItem<String>>((String value) {
|
items: formatList.map<DropdownMenuItem<String>>((String value) {
|
||||||
|
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:notube/constants.dart';
|
import 'package:notube/constants.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:notube/states/dlFormState.dart';
|
import 'package:notube/dlForm/cubit/dl_form_cubit.dart';
|
||||||
|
|
||||||
class SubmitButton extends StatefulWidget {
|
class SubmitButton extends StatefulWidget {
|
||||||
const SubmitButton({super.key});
|
const SubmitButton({super.key});
|
||||||
|
|
@ -16,14 +16,13 @@ class _SubmitButtonState extends State<SubmitButton> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var dlForm = context.watch<DlFormState>();
|
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
constraints: BoxConstraints.tightFor(width: 200),
|
constraints: BoxConstraints.tightFor(width: 200),
|
||||||
child: MouseRegion(
|
child: MouseRegion(
|
||||||
cursor: SystemMouseCursors.click,
|
cursor: SystemMouseCursors.click,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
dlForm.download();
|
context.read<DlFormCubit>().download();
|
||||||
},
|
},
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onHover: (hovering) {
|
onHover: (hovering) {
|
||||||
|
|
@ -2,15 +2,14 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:notube/constants.dart';
|
import 'package:notube/constants.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:notube/states/dlFormState.dart';
|
import 'package:notube/dlForm/cubit/dl_form_cubit.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
class UrlTextField extends StatelessWidget {
|
class UrlTextField extends StatelessWidget {
|
||||||
const UrlTextField({super.key});
|
const UrlTextField({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var dlForm = context.watch<DlFormState>();
|
|
||||||
|
|
||||||
return Flexible(
|
return Flexible(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
|
|
@ -28,8 +27,8 @@ class UrlTextField extends StatelessWidget {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
onChanged: (value) {
|
onChanged: (newUrl) {
|
||||||
dlForm.setUrl(value);
|
context.read<DlFormCubit>().setUrl(newUrl);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -4,11 +4,9 @@ import 'package:notube/wrapper.dart';
|
||||||
import 'package:notube/constants.dart';
|
import 'package:notube/constants.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
import 'package:upgrader/upgrader.dart';
|
import 'package:upgrader/upgrader.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:redux/redux.dart';
|
import 'package:notube/videoList/cubit/videos_cubit.dart';
|
||||||
import 'package:notube/store/app.state.dart';
|
import 'package:notube/models/Video.dart';
|
||||||
import 'package:notube/store/app.reducer.dart';
|
|
||||||
import 'package:notube/store/videos/videos.state.dart';
|
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
@ -26,25 +24,17 @@ void main() async {
|
||||||
await windowManager.focus();
|
await windowManager.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
final store = Store<AppState>(
|
|
||||||
appReducer,
|
|
||||||
initialState: AppState(
|
|
||||||
videosState: VideosState.initial(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
EasyLocalization(
|
EasyLocalization(
|
||||||
supportedLocales: [Locale('en', 'US'), Locale('fr', 'FR')],
|
supportedLocales: [Locale('en', 'US'), Locale('fr', 'FR')],
|
||||||
path: 'lib/translations',
|
path: 'lib/translations',
|
||||||
fallbackLocale: Locale('en', 'US'),
|
fallbackLocale: Locale('en', 'US'),
|
||||||
child: NoTubeApp(store: store)),
|
child: NoTubeApp()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class NoTubeApp extends StatefulWidget {
|
class NoTubeApp extends StatefulWidget {
|
||||||
final Store<AppState> store;
|
const NoTubeApp({super.key});
|
||||||
const NoTubeApp({super.key, required this.store});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<NoTubeApp> createState() => _NoTubeAppState();
|
State<NoTubeApp> createState() => _NoTubeAppState();
|
||||||
|
|
@ -61,24 +51,22 @@ class _NoTubeAppState extends State<NoTubeApp> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StoreProvider<AppState>(
|
return MaterialApp(
|
||||||
store: widget.store,
|
title: 'NoTube',
|
||||||
child: MaterialApp(
|
theme: ThemeData(
|
||||||
title: 'NoTube',
|
fontFamily: 'Poppins',
|
||||||
theme: ThemeData(
|
useMaterial3: true,
|
||||||
fontFamily: 'Poppins',
|
colorScheme: ColorScheme.fromSeed(
|
||||||
useMaterial3: true,
|
seedColor: colorMainRed, brightness: Brightness.dark),
|
||||||
colorScheme: ColorScheme.fromSeed(
|
appBarTheme:
|
||||||
seedColor: colorMainRed, brightness: Brightness.dark),
|
const AppBarTheme(color: colorBackgroundBlack, elevation: 0),
|
||||||
appBarTheme: const AppBarTheme(
|
scaffoldBackgroundColor: colorMainGrey),
|
||||||
color: colorBackgroundBlack, elevation: 0),
|
localizationsDelegates: context.localizationDelegates,
|
||||||
scaffoldBackgroundColor: colorMainGrey),
|
supportedLocales: context.supportedLocales,
|
||||||
localizationsDelegates: context.localizationDelegates,
|
locale: context.locale,
|
||||||
supportedLocales: context.supportedLocales,
|
home: BlocProvider(
|
||||||
locale: context.locale,
|
create: (context) => VideosCubit(),
|
||||||
home: StoreBuilder<AppState>(
|
child: UpgradeAlert(upgrader: upgrader, child: const Wrapper())),
|
||||||
builder: (BuildContext context, Store<AppState> store) =>
|
);
|
||||||
UpgradeAlert(upgrader: upgrader, child: const Wrapper()),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,6 @@
|
||||||
import 'dart:developer' as developer;
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
class Video {
|
|
||||||
String id;
|
|
||||||
String title;
|
|
||||||
String thumbnail;
|
|
||||||
String description;
|
|
||||||
String duration;
|
|
||||||
String uploader;
|
|
||||||
String uploadDate;
|
|
||||||
|
|
||||||
|
class Video extends Equatable {
|
||||||
Video({
|
Video({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.title,
|
required this.title,
|
||||||
|
|
@ -19,6 +11,14 @@ class Video {
|
||||||
required this.uploadDate,
|
required this.uploadDate,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
String id;
|
||||||
|
String title;
|
||||||
|
String thumbnail;
|
||||||
|
String description;
|
||||||
|
String duration;
|
||||||
|
String uploader;
|
||||||
|
String uploadDate;
|
||||||
|
|
||||||
factory Video.fromJson(Map<String, dynamic> json) {
|
factory Video.fromJson(Map<String, dynamic> json) {
|
||||||
return Video(
|
return Video(
|
||||||
id: json['id'],
|
id: json['id'],
|
||||||
|
|
@ -29,4 +29,8 @@ class Video {
|
||||||
uploader: json['uploader'] ?? '',
|
uploader: json['uploader'] ?? '',
|
||||||
uploadDate: json['upload_date'] ?? '');
|
uploadDate: json['upload_date'] ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props =>
|
||||||
|
[id, title, thumbnail, description, duration, uploader, uploadDate];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:notube/constants.dart';
|
import 'package:notube/constants.dart';
|
||||||
import 'package:notube/components/dlForm.dart';
|
import 'package:notube/dlForm/dlForm.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:notube/videoList/cubit/videos_cubit.dart';
|
||||||
|
import 'package:notube/models/Video.dart';
|
||||||
|
|
||||||
class Home extends StatelessWidget {
|
class Home extends StatelessWidget {
|
||||||
Home({super.key});
|
Home({super.key});
|
||||||
|
|
@ -28,7 +31,18 @@ class Home extends StatelessWidget {
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||||
child: DlForm())
|
child: DlForm()),
|
||||||
|
BlocConsumer<VideosCubit, VideosState>(
|
||||||
|
listener: (context, state) {},
|
||||||
|
builder: (context, state) {
|
||||||
|
return Column(
|
||||||
|
children: <Widget>[
|
||||||
|
for (Video video
|
||||||
|
in context.read<VideosCubit>().videoList)
|
||||||
|
Text(video.title),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:notube/models/Video.dart';
|
import 'package:notube/models/Video.dart';
|
||||||
import 'package:notube/states/dlFormState.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:notube/videoList/cubit/videos_cubit.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:process_run/shell.dart';
|
import 'package:process_run/shell.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:notube/services/download.dart';
|
|
||||||
|
|
||||||
class DlFormState extends ChangeNotifier {
|
|
||||||
String url =
|
|
||||||
'https://youtu.be/playlist?list=PLk1fi9OrZmvGBdh9BdWIhZImGVDUqls1X';
|
|
||||||
String format = 'MP3';
|
|
||||||
|
|
||||||
late DLServices dlService;
|
|
||||||
|
|
||||||
void setUrl(String newUrl) {
|
|
||||||
url = newUrl;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFormat(String newFormat) {
|
|
||||||
format = newFormat;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> download() async {
|
|
||||||
dlService = await DLServices.init();
|
|
||||||
await dlService.analyseUrl(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
|
|
||||||
import 'package:redux/redux.dart';
|
|
||||||
import './app.state.dart';
|
|
||||||
|
|
||||||
List<Middleware<AppState>> appMiddleware() {
|
|
||||||
// final Middleware<AppState> _login = login(_repo);
|
|
||||||
|
|
||||||
return [
|
|
||||||
// TypedMiddleware<AppState, LoginAction>(_login),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
import 'package:notube/store/videos/videos.reducer.dart';
|
|
||||||
|
|
||||||
import './app.state.dart';
|
|
||||||
|
|
||||||
AppState appReducer(AppState state, action) => AppState(
|
|
||||||
videosState: videosReducer(state.videosState, action),
|
|
||||||
);
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import 'package:notube/store/videos/videos.state.dart';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class AppState {
|
|
||||||
final VideosState videosState;
|
|
||||||
|
|
||||||
AppState({required this.videosState});
|
|
||||||
|
|
||||||
factory AppState.initial() => AppState(
|
|
||||||
videosState: VideosState.initial(),
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(other) =>
|
|
||||||
identical(this, other) ||
|
|
||||||
other is AppState &&
|
|
||||||
runtimeType == other.runtimeType &&
|
|
||||||
videosState == other.videosState;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => super.hashCode ^ videosState.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return "AppState { videosState: $videosState }";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class VideosAction {
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'VideosAction { }';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class VideosSuccessAction {
|
|
||||||
final int isSuccess;
|
|
||||||
|
|
||||||
VideosSuccessAction({required this.isSuccess});
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'VideosSuccessAction { isSuccess: $isSuccess }';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class VideosFailedAction {
|
|
||||||
final String error;
|
|
||||||
|
|
||||||
VideosFailedAction({required this.error});
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'VideosFailedAction { error: $error }';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import 'package:redux/redux.dart';
|
|
||||||
import 'package:notube/store/app.state.dart';
|
|
||||||
import 'package:notube/models/Video.dart';
|
|
||||||
|
|
||||||
Middleware<AppState> getVideos(Video _video) {
|
|
||||||
return (Store<AppState> store, action, NextDispatcher dispatch) async {
|
|
||||||
dispatch(action);
|
|
||||||
try {
|
|
||||||
// TODO: Write here your middleware logic and api calls
|
|
||||||
} catch (error) {
|
|
||||||
// TODO: API Error handling
|
|
||||||
print(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
import 'package:redux/redux.dart';
|
|
||||||
import 'videos.state.dart';
|
|
||||||
|
|
||||||
final videosReducer = combineReducers<VideosState>([]);
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
|
|
||||||
class VideosState {
|
|
||||||
final bool loading;
|
|
||||||
final String error;
|
|
||||||
|
|
||||||
VideosState(this.loading, this.error);
|
|
||||||
|
|
||||||
factory VideosState.initial() => VideosState(false, '');
|
|
||||||
|
|
||||||
VideosState copyWith({bool? loading, String? error}) =>
|
|
||||||
VideosState(loading ?? this.loading, error ?? this.error);
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(other) =>
|
|
||||||
identical(this, other) ||
|
|
||||||
other is VideosState &&
|
|
||||||
runtimeType == other.runtimeType &&
|
|
||||||
loading == other.loading &&
|
|
||||||
error == other.error;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
super.hashCode ^ runtimeType.hashCode ^ loading.hashCode ^ error.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => "VideosState { loading: $loading, error: $error}";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:notube/models/Video.dart';
|
||||||
|
|
||||||
|
part 'videos_state.dart';
|
||||||
|
|
||||||
|
class VideosCubit extends Cubit<VideosState> {
|
||||||
|
VideosCubit() : super(VideosState());
|
||||||
|
|
||||||
|
final List<Video> _videoList = [];
|
||||||
|
List<Video> get videoList => _videoList;
|
||||||
|
|
||||||
|
void addVideo(Video video) {
|
||||||
|
_videoList.add(video);
|
||||||
|
emit(VideosState(videoList: _videoList));
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearVideos() {
|
||||||
|
_videoList.clear();
|
||||||
|
emit(VideosState(videoList: _videoList));
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeVideo(Video video) {
|
||||||
|
_videoList.remove(video);
|
||||||
|
emit(VideosState(videoList: _videoList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
part of 'videos_cubit.dart';
|
||||||
|
|
||||||
|
final class VideosState extends Equatable {
|
||||||
|
final List<Video> videoList;
|
||||||
|
|
||||||
|
VideosState({this.videoList = const []});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [videoList];
|
||||||
|
}
|
||||||
16
pubspec.lock
16
pubspec.lock
|
|
@ -105,6 +105,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
|
equatable:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: equatable
|
||||||
|
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.5"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -221,6 +229,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.19.0"
|
version: "0.19.0"
|
||||||
|
json_annotation:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: json_annotation
|
||||||
|
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.9.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||||
version: 0.0.1+1
|
version: 0.0.1+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.19.4 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
|
@ -25,6 +25,8 @@ dependencies:
|
||||||
redux: ^5.0.0
|
redux: ^5.0.0
|
||||||
redux_thunk: ^0.4.0
|
redux_thunk: ^0.4.0
|
||||||
flutter_bloc: ^8.1.6
|
flutter_bloc: ^8.1.6
|
||||||
|
equatable: ^2.0.5
|
||||||
|
json_annotation: ^4.9.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue