Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

気象庁による 地震・津波のお知らせ #529

Merged
merged 5 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 56 additions & 8 deletions lib/core/extension/async_value.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,64 @@
import 'dart:async';
// ignore_for_file: avoid_positional_boolean_parameters

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

extension AsyncValueExt<T> on AsyncValue<T> {
Future<AsyncValue<T>> guardPlus(
Future<T> Function() future,
) async {
// https://zenn.dev/k9i/articles/b8c333e1bb8b9b
extension AsyncValueX<T> on AsyncValue<T> {
/// guard関数の拡張版
/// 例外時に前回のデータを持たせてエラーを返す
Future<AsyncValue<T>> guardPlus(Future<T> Function() future) async {
try {
return AsyncValue<T>.data(await future());
return AsyncValue.data(await future());
// ignore: avoid_catches_without_on_clauses
} catch (e, st) {
return AsyncValue<T>.error(e, st).copyWithPrevious(this);
} catch (err, stack) {
// 前回のデータを持たせてエラーを返す
return AsyncValue<T>.error(err, stack).copyWithPrevious(this);
}
}

/// when関数の拡張版
///
/// [skipErrorOnHasValue]がtrueの時はデータがある場合のエラーをスキップする
/// ページングの2ページ目以降でエラー時に、取得ずみデータを表示する場合などに使用する
R whenPlus<R>({
bool skipLoadingOnReload = false,
bool skipLoadingOnRefresh = true,
bool skipError = false,
bool skipErrorOnHasValue = false,
required R Function(T data, bool hasError) data,
required R Function(Object error, StackTrace stackTrace) error,
required R Function() loading,
}) {
if (skipErrorOnHasValue) {
if (hasValue && hasError) {
return data(requireValue, true);
}
}

return when(
skipLoadingOnReload: skipLoadingOnReload,
skipLoadingOnRefresh: skipLoadingOnRefresh,
skipError: skipError,
data: (d) => data(d, hasError),
error: error,
loading: loading,
);
}

/// エラー時にスナックバーを表示する
void showSnackbarOnError(
BuildContext context, {
String defaultMessage = 'エラーが発生しました',
}) {
if (!isLoading && hasError) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
error!.toString(),
),
),
);
}
}
}
56 changes: 36 additions & 20 deletions lib/core/foundation/result.dart
Original file line number Diff line number Diff line change
@@ -1,27 +1,43 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';

part 'result.freezed.dart';
/// sealed classに準拠したResultクラスを生成
sealed class Result<S, E extends Exception> {
const Result();

@freezed
sealed class Result<T, R> with _$Result<T, R> {
const Result._();
const factory Result.success(T value) = Success<T, R>;
const factory Result.failure(R error) = Failure<T, R>;
static Future<Result<V, Exception>> capture<V>(
FutureOr<V> Function() fn,
) async {
try {
return Success(await fn.call());
} on Exception catch (e, stackTrace) {
return Failure(e, stackTrace);
}
}

T? get valueOrNull => when(
success: (value) => value,
failure: (_) => null,
);
static Future<Result<V, E>> captureSelected<V, E extends Exception>(
FutureOr<V> Function() fn,
) async {
try {
return Success(await fn.call());
} on E catch (e, stackTrace) {
return Failure(e, stackTrace);
}
}

R? get errorOrNull => when(
success: (_) => null,
failure: (error) => error,
);
static Result<V, Exception> success<V>(V value) => Success(value);
static Result<V, Exception> failure<V>(Exception exception) =>
Failure(exception);
}

bool get isSuccess => when(
success: (_) => true,
failure: (_) => false,
);
/// Resultクラスに準拠したSuccessクラス
final class Success<S, E extends Exception> extends Result<S, E> {
const Success(this.value);
final S value;
}

bool get isFailure => !isSuccess;
/// Resultクラスに準拠したFailureクラス
final class Failure<S, E extends Exception> extends Result<S, E> {
const Failure(this.exception, [this.stackTrace]);
final E exception;
final StackTrace? stackTrace;
}
Loading
Loading