wip: env models, provider

This commit is contained in:
DenserMeerkat
2024-06-07 16:58:07 +05:30
parent a49bcec641
commit 6aa959cbee
11 changed files with 804 additions and 12 deletions

View File

@ -259,6 +259,8 @@ enum HTTPVerb { get, head, post, put, patch, delete }
enum FormDataType { text, file } enum FormDataType { text, file }
enum EnvironmentVariableType { variable, secret }
const kSupportedUriSchemes = ["https", "http"]; const kSupportedUriSchemes = ["https", "http"];
const kDefaultUriScheme = "https"; const kDefaultUriScheme = "https";
const kMethodsWithBody = [ const kMethodsWithBody = [
@ -311,6 +313,8 @@ enum CodegenLanguage {
const JsonEncoder kEncoder = JsonEncoder.withIndent(' '); const JsonEncoder kEncoder = JsonEncoder.withIndent(' ');
const LineSplitter kSplitter = LineSplitter(); const LineSplitter kSplitter = LineSplitter();
const String kGlobalEnvironmentId = "global";
const kHeaderContentType = "Content-Type"; const kHeaderContentType = "Content-Type";
const kTypeApplication = 'application'; const kTypeApplication = 'application';

View File

@ -0,0 +1,81 @@
import 'package:flutter/foundation.dart';
import 'environment_model.dart';
@immutable
class EnvironmentListModel {
const EnvironmentListModel({
this.actveEnvironment,
this.globalEnvironment = const EnvironmentModel(id: "global"),
this.environments = const [],
});
final EnvironmentModel? actveEnvironment;
final EnvironmentModel globalEnvironment;
final List<EnvironmentModel> environments;
EnvironmentListModel copyWith({
EnvironmentModel? actveEnvironment,
EnvironmentModel? globalEnvironment,
List<EnvironmentModel>? environments,
}) {
return EnvironmentListModel(
actveEnvironment: actveEnvironment ?? this.actveEnvironment,
globalEnvironment: globalEnvironment ?? this.globalEnvironment,
environments: environments ?? this.environments,
);
}
factory EnvironmentListModel.fromJson(Map<dynamic, dynamic> data) {
final actveEnvironment = data["actveEnvironment"] != null
? EnvironmentModel.fromJson(
data["actveEnvironment"] as Map<String, dynamic>)
: null;
final globalEnvironment = EnvironmentModel.fromJson(
data["globalEnvironment"] as Map<String, dynamic>);
final List<dynamic> environments = data["environments"] as List<dynamic>;
const em = EnvironmentListModel();
return em.copyWith(
actveEnvironment: actveEnvironment,
globalEnvironment: globalEnvironment,
environments: environments
.map((dynamic e) =>
EnvironmentModel.fromJson(e as Map<String, dynamic>))
.toList(),
);
}
Map<String, dynamic> toJson() {
return {
"actveEnvironment": actveEnvironment?.toJson(),
"globalEnvironment": globalEnvironment.toJson(),
"environments": environments.map((e) => e.toJson()).toList(),
};
}
EnvironmentModel getEnvironment(String id) {
if (id == "global") {
return globalEnvironment;
}
return environments.firstWhere((e) => e.id == id);
}
@override
bool operator ==(Object other) {
return other is EnvironmentListModel &&
other.actveEnvironment == actveEnvironment &&
other.globalEnvironment == globalEnvironment &&
listEquals(other.environments, environments);
}
@override
int get hashCode {
return Object.hash(
actveEnvironment,
globalEnvironment,
environments,
);
}
}

View File

@ -0,0 +1,34 @@
import 'package:apidash/consts.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'environment_model.freezed.dart';
part 'environment_model.g.dart';
@freezed
class EnvironmentModel with _$EnvironmentModel {
const factory EnvironmentModel({
required String id,
@Default("") String name,
@Default([]) List<EnvironmentVariableModel> values,
}) = _EnvironmentModel;
factory EnvironmentModel.fromJson(Map<String, Object?> json) =>
_$EnvironmentModelFromJson(json);
}
@freezed
class EnvironmentVariableModel with _$EnvironmentVariableModel {
const factory EnvironmentVariableModel({
required String key,
required String value,
@Default(EnvironmentVariableType.variable) EnvironmentVariableType type,
@Default(true) bool enabled,
}) = _EnvironmentVariableModel;
factory EnvironmentVariableModel.fromJson(Map<String, Object?> json) =>
_$EnvironmentVariableModelFromJson(json);
}
const kEnvironmentVariableEmptyModel =
EnvironmentVariableModel(key: "", value: "");

View File

@ -0,0 +1,402 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'environment_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
EnvironmentModel _$EnvironmentModelFromJson(Map<String, dynamic> json) {
return _EnvironmentModel.fromJson(json);
}
/// @nodoc
mixin _$EnvironmentModel {
String get id => throw _privateConstructorUsedError;
String get name => throw _privateConstructorUsedError;
List<EnvironmentVariableModel> get values =>
throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$EnvironmentModelCopyWith<EnvironmentModel> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $EnvironmentModelCopyWith<$Res> {
factory $EnvironmentModelCopyWith(
EnvironmentModel value, $Res Function(EnvironmentModel) then) =
_$EnvironmentModelCopyWithImpl<$Res, EnvironmentModel>;
@useResult
$Res call({String id, String name, List<EnvironmentVariableModel> values});
}
/// @nodoc
class _$EnvironmentModelCopyWithImpl<$Res, $Val extends EnvironmentModel>
implements $EnvironmentModelCopyWith<$Res> {
_$EnvironmentModelCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? name = null,
Object? values = null,
}) {
return _then(_value.copyWith(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
values: null == values
? _value.values
: values // ignore: cast_nullable_to_non_nullable
as List<EnvironmentVariableModel>,
) as $Val);
}
}
/// @nodoc
abstract class _$$EnvironmentModelImplCopyWith<$Res>
implements $EnvironmentModelCopyWith<$Res> {
factory _$$EnvironmentModelImplCopyWith(_$EnvironmentModelImpl value,
$Res Function(_$EnvironmentModelImpl) then) =
__$$EnvironmentModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({String id, String name, List<EnvironmentVariableModel> values});
}
/// @nodoc
class __$$EnvironmentModelImplCopyWithImpl<$Res>
extends _$EnvironmentModelCopyWithImpl<$Res, _$EnvironmentModelImpl>
implements _$$EnvironmentModelImplCopyWith<$Res> {
__$$EnvironmentModelImplCopyWithImpl(_$EnvironmentModelImpl _value,
$Res Function(_$EnvironmentModelImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? name = null,
Object? values = null,
}) {
return _then(_$EnvironmentModelImpl(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
values: null == values
? _value._values
: values // ignore: cast_nullable_to_non_nullable
as List<EnvironmentVariableModel>,
));
}
}
/// @nodoc
@JsonSerializable()
class _$EnvironmentModelImpl implements _EnvironmentModel {
const _$EnvironmentModelImpl(
{required this.id,
this.name = "",
final List<EnvironmentVariableModel> values = const []})
: _values = values;
factory _$EnvironmentModelImpl.fromJson(Map<String, dynamic> json) =>
_$$EnvironmentModelImplFromJson(json);
@override
final String id;
@override
@JsonKey()
final String name;
final List<EnvironmentVariableModel> _values;
@override
@JsonKey()
List<EnvironmentVariableModel> get values {
if (_values is EqualUnmodifiableListView) return _values;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_values);
}
@override
String toString() {
return 'EnvironmentModel(id: $id, name: $name, values: $values)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$EnvironmentModelImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.name, name) || other.name == name) &&
const DeepCollectionEquality().equals(other._values, _values));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(
runtimeType, id, name, const DeepCollectionEquality().hash(_values));
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$EnvironmentModelImplCopyWith<_$EnvironmentModelImpl> get copyWith =>
__$$EnvironmentModelImplCopyWithImpl<_$EnvironmentModelImpl>(
this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$EnvironmentModelImplToJson(
this,
);
}
}
abstract class _EnvironmentModel implements EnvironmentModel {
const factory _EnvironmentModel(
{required final String id,
final String name,
final List<EnvironmentVariableModel> values}) = _$EnvironmentModelImpl;
factory _EnvironmentModel.fromJson(Map<String, dynamic> json) =
_$EnvironmentModelImpl.fromJson;
@override
String get id;
@override
String get name;
@override
List<EnvironmentVariableModel> get values;
@override
@JsonKey(ignore: true)
_$$EnvironmentModelImplCopyWith<_$EnvironmentModelImpl> get copyWith =>
throw _privateConstructorUsedError;
}
EnvironmentVariableModel _$EnvironmentVariableModelFromJson(
Map<String, dynamic> json) {
return _EnvironmentVariableModel.fromJson(json);
}
/// @nodoc
mixin _$EnvironmentVariableModel {
String get key => throw _privateConstructorUsedError;
String get value => throw _privateConstructorUsedError;
EnvironmentVariableType get type => throw _privateConstructorUsedError;
bool get enabled => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$EnvironmentVariableModelCopyWith<EnvironmentVariableModel> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $EnvironmentVariableModelCopyWith<$Res> {
factory $EnvironmentVariableModelCopyWith(EnvironmentVariableModel value,
$Res Function(EnvironmentVariableModel) then) =
_$EnvironmentVariableModelCopyWithImpl<$Res, EnvironmentVariableModel>;
@useResult
$Res call(
{String key, String value, EnvironmentVariableType type, bool enabled});
}
/// @nodoc
class _$EnvironmentVariableModelCopyWithImpl<$Res,
$Val extends EnvironmentVariableModel>
implements $EnvironmentVariableModelCopyWith<$Res> {
_$EnvironmentVariableModelCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? key = null,
Object? value = null,
Object? type = null,
Object? enabled = null,
}) {
return _then(_value.copyWith(
key: null == key
? _value.key
: key // ignore: cast_nullable_to_non_nullable
as String,
value: null == value
? _value.value
: value // ignore: cast_nullable_to_non_nullable
as String,
type: null == type
? _value.type
: type // ignore: cast_nullable_to_non_nullable
as EnvironmentVariableType,
enabled: null == enabled
? _value.enabled
: enabled // ignore: cast_nullable_to_non_nullable
as bool,
) as $Val);
}
}
/// @nodoc
abstract class _$$EnvironmentVariableModelImplCopyWith<$Res>
implements $EnvironmentVariableModelCopyWith<$Res> {
factory _$$EnvironmentVariableModelImplCopyWith(
_$EnvironmentVariableModelImpl value,
$Res Function(_$EnvironmentVariableModelImpl) then) =
__$$EnvironmentVariableModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{String key, String value, EnvironmentVariableType type, bool enabled});
}
/// @nodoc
class __$$EnvironmentVariableModelImplCopyWithImpl<$Res>
extends _$EnvironmentVariableModelCopyWithImpl<$Res,
_$EnvironmentVariableModelImpl>
implements _$$EnvironmentVariableModelImplCopyWith<$Res> {
__$$EnvironmentVariableModelImplCopyWithImpl(
_$EnvironmentVariableModelImpl _value,
$Res Function(_$EnvironmentVariableModelImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? key = null,
Object? value = null,
Object? type = null,
Object? enabled = null,
}) {
return _then(_$EnvironmentVariableModelImpl(
key: null == key
? _value.key
: key // ignore: cast_nullable_to_non_nullable
as String,
value: null == value
? _value.value
: value // ignore: cast_nullable_to_non_nullable
as String,
type: null == type
? _value.type
: type // ignore: cast_nullable_to_non_nullable
as EnvironmentVariableType,
enabled: null == enabled
? _value.enabled
: enabled // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
@JsonSerializable()
class _$EnvironmentVariableModelImpl implements _EnvironmentVariableModel {
const _$EnvironmentVariableModelImpl(
{required this.key,
required this.value,
this.type = EnvironmentVariableType.variable,
this.enabled = true});
factory _$EnvironmentVariableModelImpl.fromJson(Map<String, dynamic> json) =>
_$$EnvironmentVariableModelImplFromJson(json);
@override
final String key;
@override
final String value;
@override
@JsonKey()
final EnvironmentVariableType type;
@override
@JsonKey()
final bool enabled;
@override
String toString() {
return 'EnvironmentVariableModel(key: $key, value: $value, type: $type, enabled: $enabled)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$EnvironmentVariableModelImpl &&
(identical(other.key, key) || other.key == key) &&
(identical(other.value, value) || other.value == value) &&
(identical(other.type, type) || other.type == type) &&
(identical(other.enabled, enabled) || other.enabled == enabled));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(runtimeType, key, value, type, enabled);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$EnvironmentVariableModelImplCopyWith<_$EnvironmentVariableModelImpl>
get copyWith => __$$EnvironmentVariableModelImplCopyWithImpl<
_$EnvironmentVariableModelImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$EnvironmentVariableModelImplToJson(
this,
);
}
}
abstract class _EnvironmentVariableModel implements EnvironmentVariableModel {
const factory _EnvironmentVariableModel(
{required final String key,
required final String value,
final EnvironmentVariableType type,
final bool enabled}) = _$EnvironmentVariableModelImpl;
factory _EnvironmentVariableModel.fromJson(Map<String, dynamic> json) =
_$EnvironmentVariableModelImpl.fromJson;
@override
String get key;
@override
String get value;
@override
EnvironmentVariableType get type;
@override
bool get enabled;
@override
@JsonKey(ignore: true)
_$$EnvironmentVariableModelImplCopyWith<_$EnvironmentVariableModelImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,52 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'environment_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$EnvironmentModelImpl _$$EnvironmentModelImplFromJson(
Map<String, dynamic> json) =>
_$EnvironmentModelImpl(
id: json['id'] as String,
name: json['name'] as String? ?? "",
values: (json['values'] as List<dynamic>?)
?.map((e) =>
EnvironmentVariableModel.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
);
Map<String, dynamic> _$$EnvironmentModelImplToJson(
_$EnvironmentModelImpl instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'values': instance.values,
};
_$EnvironmentVariableModelImpl _$$EnvironmentVariableModelImplFromJson(
Map<String, dynamic> json) =>
_$EnvironmentVariableModelImpl(
key: json['key'] as String,
value: json['value'] as String,
type:
$enumDecodeNullable(_$EnvironmentVariableTypeEnumMap, json['type']) ??
EnvironmentVariableType.variable,
enabled: json['enabled'] as bool? ?? true,
);
Map<String, dynamic> _$$EnvironmentVariableModelImplToJson(
_$EnvironmentVariableModelImpl instance) =>
<String, dynamic>{
'key': instance.key,
'value': instance.value,
'type': _$EnvironmentVariableTypeEnumMap[instance.type]!,
'enabled': instance.enabled,
};
const _$EnvironmentVariableTypeEnumMap = {
EnvironmentVariableType.variable: 'variable',
EnvironmentVariableType.secret: 'secret',
};

View File

@ -1,3 +1,4 @@
export 'environment_model.dart';
export 'form_data_model.dart'; export 'form_data_model.dart';
export 'http_request_model.dart'; export 'http_request_model.dart';
export 'http_response_model.dart'; export 'http_response_model.dart';

View File

@ -12,6 +12,7 @@ class SettingsModel {
this.defaultCodeGenLang = CodegenLanguage.curl, this.defaultCodeGenLang = CodegenLanguage.curl,
this.saveResponses = true, this.saveResponses = true,
this.promptBeforeClosing = true, this.promptBeforeClosing = true,
this.activeEnvironmentId,
}); });
final bool isDark; final bool isDark;
@ -22,6 +23,7 @@ class SettingsModel {
final CodegenLanguage defaultCodeGenLang; final CodegenLanguage defaultCodeGenLang;
final bool saveResponses; final bool saveResponses;
final bool promptBeforeClosing; final bool promptBeforeClosing;
final String? activeEnvironmentId;
SettingsModel copyWith({ SettingsModel copyWith({
bool? isDark, bool? isDark,
@ -32,6 +34,7 @@ class SettingsModel {
CodegenLanguage? defaultCodeGenLang, CodegenLanguage? defaultCodeGenLang,
bool? saveResponses, bool? saveResponses,
bool? promptBeforeClosing, bool? promptBeforeClosing,
String? activeEnvironmentId,
}) { }) {
return SettingsModel( return SettingsModel(
isDark: isDark ?? this.isDark, isDark: isDark ?? this.isDark,
@ -43,6 +46,7 @@ class SettingsModel {
offset: offset ?? this.offset, offset: offset ?? this.offset,
saveResponses: saveResponses ?? this.saveResponses, saveResponses: saveResponses ?? this.saveResponses,
promptBeforeClosing: promptBeforeClosing ?? this.promptBeforeClosing, promptBeforeClosing: promptBeforeClosing ?? this.promptBeforeClosing,
activeEnvironmentId: activeEnvironmentId ?? this.activeEnvironmentId,
); );
} }
@ -75,18 +79,20 @@ class SettingsModel {
} }
final saveResponses = data["saveResponses"] as bool?; final saveResponses = data["saveResponses"] as bool?;
final promptBeforeClosing = data["promptBeforeClosing"] as bool?; final promptBeforeClosing = data["promptBeforeClosing"] as bool?;
final activeEnvironmentId = data["activeEnvironmentId"] as String?;
const sm = SettingsModel(); const sm = SettingsModel();
return sm.copyWith( return sm.copyWith(
isDark: isDark, isDark: isDark,
alwaysShowCollectionPaneScrollbar: alwaysShowCollectionPaneScrollbar, alwaysShowCollectionPaneScrollbar: alwaysShowCollectionPaneScrollbar,
size: size, size: size,
offset: offset, offset: offset,
defaultUriScheme: defaultUriScheme, defaultUriScheme: defaultUriScheme,
defaultCodeGenLang: defaultCodeGenLang, defaultCodeGenLang: defaultCodeGenLang,
saveResponses: saveResponses, saveResponses: saveResponses,
promptBeforeClosing: promptBeforeClosing); promptBeforeClosing: promptBeforeClosing,
activeEnvironmentId: activeEnvironmentId,
);
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -101,6 +107,7 @@ class SettingsModel {
"defaultCodeGenLang": defaultCodeGenLang.name, "defaultCodeGenLang": defaultCodeGenLang.name,
"saveResponses": saveResponses, "saveResponses": saveResponses,
"promptBeforeClosing": promptBeforeClosing, "promptBeforeClosing": promptBeforeClosing,
"activeEnvironmentId": activeEnvironmentId,
}; };
} }
@ -121,7 +128,8 @@ class SettingsModel {
other.defaultUriScheme == defaultUriScheme && other.defaultUriScheme == defaultUriScheme &&
other.defaultCodeGenLang == defaultCodeGenLang && other.defaultCodeGenLang == defaultCodeGenLang &&
other.saveResponses == saveResponses && other.saveResponses == saveResponses &&
other.promptBeforeClosing == promptBeforeClosing; other.promptBeforeClosing == promptBeforeClosing &&
other.activeEnvironmentId == activeEnvironmentId;
} }
@override @override
@ -136,6 +144,7 @@ class SettingsModel {
defaultCodeGenLang, defaultCodeGenLang,
saveResponses, saveResponses,
promptBeforeClosing, promptBeforeClosing,
activeEnvironmentId,
); );
} }
} }

View File

@ -0,0 +1,174 @@
import 'package:apidash/consts.dart';
import 'package:apidash/models/environment_model.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/utils/file_utils.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../services/services.dart' show hiveHandler, HiveHandler;
final selectedEnvironmentIdProvider = StateProvider<String?>((ref) => null);
final environmentsStateNotifierProvider = StateNotifierProvider<
EnvironmentsStateNotifier, Map<String, EnvironmentModel>?>((ref) {
return EnvironmentsStateNotifier(ref, hiveHandler);
});
final environmentSequenceProvider = StateProvider<List<String>>((ref) {
var ids = hiveHandler.getEnvironmentIds();
return ids ?? [];
});
class EnvironmentsStateNotifier
extends StateNotifier<Map<String, EnvironmentModel>?> {
EnvironmentsStateNotifier(this.ref, this.hiveHandler) : super(null) {
var status = loadEnvironments();
Future.microtask(() {
if (status) {
ref.read(environmentSequenceProvider.notifier).state = [
state!.keys.first,
];
}
ref.read(selectedEnvironmentIdProvider.notifier).state =
ref.read(environmentSequenceProvider)[0];
});
}
final Ref ref;
final HiveHandler hiveHandler;
bool loadEnvironments() {
List<String>? environmentIds = hiveHandler.getEnvironmentIds();
if (environmentIds == null || environmentIds.isEmpty) {
String globalId = kGlobalEnvironmentId;
const globalEnvironment = EnvironmentModel(
id: kGlobalEnvironmentId,
name: "Global",
values: [],
);
state = {
globalId: globalEnvironment,
};
return false;
} else {
Map<String, EnvironmentModel> environmentsMap = {};
for (var environmentId in environmentIds) {
var environment = hiveHandler.getEnvironment(environmentId);
EnvironmentModel environmentModelFromJson =
EnvironmentModel.fromJson(environment);
EnvironmentModel environmentModel = EnvironmentModel(
id: environmentModelFromJson.id,
name: environmentModelFromJson.name,
values: environmentModelFromJson.values,
);
environmentsMap[environmentId] = environmentModel;
}
state = environmentsMap;
return true;
}
}
void addEnvironment() {
final id = getNewUuid();
final newEnvironmentModel = EnvironmentModel(
id: id,
values: [],
);
state = {
...state!,
id: newEnvironmentModel,
};
ref
.read(environmentSequenceProvider.notifier)
.update((state) => [id, ...state]);
ref.read(selectedEnvironmentIdProvider.notifier).state =
newEnvironmentModel.id;
ref.read(hasUnsavedChangesProvider.notifier).state = true;
}
void updateEnvironment(
String id, {
String? name,
List<EnvironmentVariableModel>? values,
}) {
final environment = state![id]!;
final updatedEnvironment = environment.copyWith(
name: name ?? environment.name,
values: values ?? environment.values,
);
state = {
...state!,
id: updatedEnvironment,
};
ref.read(hasUnsavedChangesProvider.notifier).state = true;
}
void duplicateEnvironment(String id) {
final newId = getNewUuid();
final environment = state![id]!;
final newEnvironment = environment.copyWith(
id: newId,
name: "${environment.name} Copy",
);
var environmentIds = ref.read(environmentSequenceProvider);
final idx = environmentIds.indexOf(id);
environmentIds.insert(idx + 1, newId);
state = {
...state!,
newId: newEnvironment,
};
ref
.read(environmentSequenceProvider.notifier)
.update((state) => [...environmentIds]);
ref.read(selectedEnvironmentIdProvider.notifier).state = newId;
ref.read(hasUnsavedChangesProvider.notifier).state = true;
}
void removeEnvironment(String id) {
final environmentIds = ref.read(environmentSequenceProvider);
final idx = environmentIds.indexOf(id);
environmentIds.remove(id);
ref.read(environmentSequenceProvider.notifier).state = [...environmentIds];
String? newId;
if (idx == 0 && environmentIds.isNotEmpty) {
newId = environmentIds[0];
} else if (idx > 0) {
newId = environmentIds[idx - 1];
} else {
newId = kGlobalEnvironmentId;
}
ref.read(selectedEnvironmentIdProvider.notifier).state = newId;
state = {
...state!,
}..remove(id);
ref.read(hasUnsavedChangesProvider.notifier).state = true;
}
void reorder(int oldIdx, int newIdx) {
final environmentIds = ref.read(environmentSequenceProvider);
final id = environmentIds.removeAt(oldIdx);
environmentIds.insert(newIdx, id);
ref.read(environmentSequenceProvider.notifier).state = [...environmentIds];
ref.read(hasUnsavedChangesProvider.notifier).state = true;
}
void saveEnvironments() async {
ref.read(saveDataStateProvider.notifier).state = true;
final environmentIds = ref.read(environmentSequenceProvider);
hiveHandler.setEnvironmentIds(environmentIds);
for (var environmentId in environmentIds) {
var environment = state![environmentId]!;
await hiveHandler.setEnvironment(environmentId, environment.toJson());
}
await hiveHandler.removeUnused();
ref.read(saveDataStateProvider.notifier).state = false;
ref.read(hasUnsavedChangesProvider.notifier).state = false;
}
}

View File

@ -1,3 +1,4 @@
export 'collection_providers.dart'; export 'collection_providers.dart';
export 'environment_provider.dart';
export 'settings_providers.dart'; export 'settings_providers.dart';
export 'ui_providers.dart'; export 'ui_providers.dart';

View File

@ -7,6 +7,9 @@ import '../consts.dart';
final codegenLanguageStateProvider = StateProvider<CodegenLanguage>((ref) => final codegenLanguageStateProvider = StateProvider<CodegenLanguage>((ref) =>
ref.watch(settingsProvider.select((value) => value.defaultCodeGenLang))); ref.watch(settingsProvider.select((value) => value.defaultCodeGenLang)));
final activeEnvironmentIdStateProvider = StateProvider<String?>((ref) =>
ref.watch(settingsProvider.select((value) => value.activeEnvironmentId)));
final StateNotifierProvider<ThemeStateNotifier, SettingsModel> final StateNotifierProvider<ThemeStateNotifier, SettingsModel>
settingsProvider = settingsProvider =
StateNotifierProvider((ref) => ThemeStateNotifier(hiveHandler)); StateNotifierProvider((ref) => ThemeStateNotifier(hiveHandler));
@ -26,6 +29,7 @@ class ThemeStateNotifier extends StateNotifier<SettingsModel> {
CodegenLanguage? defaultCodeGenLang, CodegenLanguage? defaultCodeGenLang,
bool? saveResponses, bool? saveResponses,
bool? promptBeforeClosing, bool? promptBeforeClosing,
String? activeEnvironmentId,
}) async { }) async {
state = state.copyWith( state = state.copyWith(
isDark: isDark, isDark: isDark,
@ -36,6 +40,7 @@ class ThemeStateNotifier extends StateNotifier<SettingsModel> {
defaultCodeGenLang: defaultCodeGenLang, defaultCodeGenLang: defaultCodeGenLang,
saveResponses: saveResponses, saveResponses: saveResponses,
promptBeforeClosing: promptBeforeClosing, promptBeforeClosing: promptBeforeClosing,
activeEnvironmentId: activeEnvironmentId,
); );
await hiveHandler.saveSettings(state.toJson()); await hiveHandler.saveSettings(state.toJson());
} }

View File

@ -3,6 +3,8 @@ import 'package:hive_flutter/hive_flutter.dart';
const String kDataBox = "apidash-data"; const String kDataBox = "apidash-data";
const String kKeyDataBoxIds = "ids"; const String kKeyDataBoxIds = "ids";
const String kEnvironmentBox = "apidash-environments";
const String kKeyEnvironmentBoxIds = "environmentIds";
const String kSettingsBox = "apidash-settings"; const String kSettingsBox = "apidash-settings";
@ -10,6 +12,7 @@ Future<void> openBoxes() async {
await Hive.initFlutter(); await Hive.initFlutter();
await Hive.openBox(kDataBox); await Hive.openBox(kDataBox);
await Hive.openBox(kSettingsBox); await Hive.openBox(kSettingsBox);
await Hive.openBox(kEnvironmentBox);
} }
(Size?, Offset?) getInitialSize() { (Size?, Offset?) getInitialSize() {
@ -34,10 +37,13 @@ final hiveHandler = HiveHandler();
class HiveHandler { class HiveHandler {
late final Box dataBox; late final Box dataBox;
late final Box settingsBox; late final Box settingsBox;
late final Box environmentBox;
late final Box environmentIdsBox;
HiveHandler() { HiveHandler() {
dataBox = Hive.box(kDataBox); dataBox = Hive.box(kDataBox);
settingsBox = Hive.box(kSettingsBox); settingsBox = Hive.box(kSettingsBox);
environmentBox = Hive.box(kEnvironmentBox);
} }
Map get settings => settingsBox.toMap(); Map get settings => settingsBox.toMap();
@ -51,10 +57,24 @@ class HiveHandler {
String id, Map<String, dynamic>? requestModelJson) => String id, Map<String, dynamic>? requestModelJson) =>
dataBox.put(id, requestModelJson); dataBox.put(id, requestModelJson);
Future<int> clear() => dataBox.clear();
void delete(String key) => dataBox.delete(key); void delete(String key) => dataBox.delete(key);
dynamic getEnvironmentIds() => environmentIdsBox.get(kKeyEnvironmentBoxIds);
Future<void> setEnvironmentIds(List<String>? ids) =>
environmentIdsBox.put(kKeyEnvironmentBoxIds, ids);
dynamic getEnvironment(String id) => environmentBox.get(id);
Future<void> setEnvironment(
String id, Map<String, dynamic>? environmentJson) =>
environmentBox.put(id, environmentJson);
Future<void> deleteEnvironment(String id) => environmentBox.delete(id);
Future clear() async {
await dataBox.clear();
await environmentBox.clear();
}
Future<void> removeUnused() async { Future<void> removeUnused() async {
var ids = getIds(); var ids = getIds();
if (ids != null) { if (ids != null) {
@ -65,5 +85,14 @@ class HiveHandler {
} }
} }
} }
var environmentIds = getEnvironmentIds();
if (environmentIds != null) {
environmentIds = environmentIds as List;
for (var key in environmentBox.keys.toList()) {
if (key != kKeyEnvironmentBoxIds && !environmentIds.contains(key)) {
await environmentBox.delete(key);
}
}
}
} }
} }