Skip to content

Commit

Permalink
fix: Fixed a bug that prevented ModelCounter from working properly.
Browse files Browse the repository at this point in the history
  • Loading branch information
mathrunet committed Feb 2, 2023
1 parent d3f69fd commit 1f9bfa7
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 26 deletions.
6 changes: 5 additions & 1 deletion packages/katana_model/lib/src/document_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,11 @@ abstract class DocumentBase<T> extends ChangeNotifier
try {
_saveCompleter = Completer<T?>();
await saveRequest(_filterOnSave(toMap(newValue)));
_value = newValue;
// TODO: とりあえず消したがうまくいかないようであればまた考える
// if (value != newValue) {
// _value = newValue;
// notifyListeners();
// }
_saveCompleter?.complete(value);
_saveCompleter = null;
} catch (e) {
Expand Down
80 changes: 66 additions & 14 deletions packages/katana_model/lib/src/model_field_value.dart
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,21 @@ extension DynamicMapModelFieldValueExtensions on DynamicMap {
}
}

/// Defines where the source of the ModelFieldValue is located.
///
/// ModelFieldValueのソースがどこにあるかを定義します。
enum ModelFieldValueSource {
/// User-defined.
///
/// ユーザー定義。
user,

/// Server Definition.
///
/// サーバー定義。
server,
}

/// Define the field as a counter.
///
/// The base value is given as [value], and the value is increased or decreased by [increment].
Expand All @@ -380,26 +395,54 @@ class ModelCounter extends ModelFieldValue<int> {
/// これをサーバーに渡すことで安定して値の増減を行うことができます。
const factory ModelCounter(int value) = _ModelCounter;

/// Used to disguise the retrieval of data from the server.
///
/// Use for testing purposes.
///
/// サーバーからのデータの取得に偽装するために利用します。
///
/// テスト用途で用いてください。
const factory ModelCounter.fromServer(int value) = _ModelCounter.fromServer;

/// Convert from [json] map to [ModelCounter].
///
/// [json]のマップから[ModelCounter]に変換します。
factory ModelCounter.fromJson(DynamicMap json) {
return ModelCounter(
json.getAsInt(_kValueKey),
return _ModelCounter(
json.getAsInt(kValueKey),
ModelFieldValueSource.server,
);
}

const ModelCounter._(int value, int increment)
: _value = value,
_increment = increment;
const ModelCounter._(
int value,
int increment, [
ModelFieldValueSource source = ModelFieldValueSource.user,
]) : _value = value,
_increment = increment,
_source = source;

/// Key to store the value.
///
/// 値を保存しておくキー。
static const kValueKey = "@value";

/// Key to store the increase/decrease value.
///
/// 増減値を保存しておくキー。
static const kIncrementKey = "@increment";

static const _kValueKey = "@value";
static const _kIncrementKey = "@increment";
/// Key to store the data source.
///
/// データソースを保存しておくキー。
static const kSourceKey = "@source";

final int _value;

final int _increment;

final ModelFieldValueSource _source;

/// Obtains the increase/decrease value.
///
/// 増減値を取得します。
Expand All @@ -409,7 +452,7 @@ class ModelCounter extends ModelFieldValue<int> {
///
/// 値を[val]で増減します。
ModelCounter increment(int val) {
return ModelCounter._(_value, val);
return ModelCounter._(_value, _increment + val, _source);
}

@override
Expand All @@ -423,8 +466,9 @@ class ModelCounter extends ModelFieldValue<int> {
@override
DynamicMap toJson() => {
kTypeFieldKey: (ModelCounter).toString(),
_kValueKey: value,
_kIncrementKey: incrementValue,
kValueKey: value,
kIncrementKey: incrementValue,
kSourceKey: _source.name,
};

@override
Expand All @@ -436,7 +480,12 @@ class ModelCounter extends ModelFieldValue<int> {

@immutable
class _ModelCounter extends ModelCounter with ModelFieldValueAsMapMixin<int> {
const _ModelCounter(int value) : super._(value, 0);
const _ModelCounter(
int value, [
ModelFieldValueSource source = ModelFieldValueSource.user,
]) : super._(value, 0, source);
const _ModelCounter.fromServer(int value)
: super._(value, 0, ModelFieldValueSource.server);
}

/// [ModelFieldValueConverter] to enable automatic conversion of [ModelCounter] as [ModelFieldValue].
Expand Down Expand Up @@ -491,15 +540,18 @@ class ModelTimestamp extends ModelFieldValue<DateTime> {
/// [json]のマップから[ModelTimestamp]に変換します。
factory ModelTimestamp.fromJson(DynamicMap json) {
final timestamp = json.get(
_kTimeKey,
kTimeKey,
DateTime.now().millisecondsSinceEpoch,
);
return ModelTimestamp(DateTime.fromMillisecondsSinceEpoch(timestamp));
}

const ModelTimestamp._([DateTime? value]) : _value = value;

static const _kTimeKey = "@time";
/// Key to save time.
///
/// 時間を保存しておくキー。
static const kTimeKey = "@time";

@override
DateTime get value => _value ?? DateTime.now();
Expand All @@ -513,7 +565,7 @@ class ModelTimestamp extends ModelFieldValue<DateTime> {
@override
DynamicMap toJson() => {
kTypeFieldKey: (ModelTimestamp).toString(),
_kTimeKey: value.millisecondsSinceEpoch,
kTimeKey: value.millisecondsSinceEpoch,
};

@override
Expand Down
16 changes: 8 additions & 8 deletions packages/katana_model/test/model_field_value_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ void main() {
expect(
model.value,
{
"counter": const ModelCounter(0),
"counter": const ModelCounter.fromServer(0),
"time": ModelTimestamp(DateTime(2022, 1, 1))
},
);
await model2.load();
expect(
model2.value,
{
"counter": const ModelCounter(0),
"counter": const ModelCounter.fromServer(0),
"time": ModelTimestamp(DateTime(2022, 1, 1))
},
);
Expand All @@ -96,7 +96,7 @@ void main() {
expect(
model.value,
{
"counter": const ModelCounter(0).increment(1),
"counter": const ModelCounter.fromServer(1),
"time": ModelTimestamp(DateTime(2022, 1, 2))
},
);
Expand All @@ -115,15 +115,15 @@ void main() {
expect(
model.value,
TestValue(
counter: const ModelCounter(0),
counter: const ModelCounter.fromServer(0),
time: ModelTimestamp(DateTime(2022, 1, 1)),
),
);
await model2.load();
expect(
model2.value,
TestValue(
counter: const ModelCounter(0),
counter: const ModelCounter.fromServer(0),
time: ModelTimestamp(DateTime(2022, 1, 1)),
),
);
Expand All @@ -136,11 +136,11 @@ void main() {
),
);
expect(
model.value.hashCode,
model.value,
TestValue(
counter: const ModelCounter(0).increment(1),
counter: const ModelCounter.fromServer(1),
time: ModelTimestamp(DateTime(2022, 1, 2)),
).hashCode,
),
);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,13 +292,22 @@ class FirestoreModelAdapter extends ModelAdapter {
if (val is DynamicMap && val.containsKey(_kTypeKey)) {
final type = val.get(_kTypeKey, "");
if (type == (ModelCounter).toString()) {
final counter = ModelCounter.fromJson(val);
final fromUser = val.get(ModelCounter.kSourceKey, "") ==
ModelFieldValueSource.user.name;
final value = val.get(ModelCounter.kValueKey, 0);
final increment = val.get(ModelCounter.kIncrementKey, 0);
final targetKey = "#$key";
res[key] = {
...counter.toJson(),
kTypeFieldKey: (ModelCounter).toString(),
ModelCounter.kValueKey: value,
ModelCounter.kIncrementKey: increment,
_kTargetKey: targetKey,
};
res[targetKey] = FieldValue.increment(counter.incrementValue);
if (fromUser) {
res[targetKey] = value;
} else {
res[targetKey] = FieldValue.increment(increment);
}
} else if (type == (ModelTimestamp).toString()) {
final timestamp = ModelTimestamp.fromJson(val);
final targetKey = "#$key";
Expand Down

0 comments on commit 1f9bfa7

Please sign in to comment.