Skip to content

Commit

Permalink
重新实现物品管理页面 (#17)
Browse files Browse the repository at this point in the history
* 调整 IOT 和博客页面显示
* 提交日期时使用 UTC 时间
* 仅在手机客户端上注册 Shortcut
* 物品属性新增添加时间
* 更新物品管理主页展示
* 添加登录提示
* 获取一年内要过期的物品
* 添加位置指示 close #15
  • Loading branch information
he0119 authored Mar 13, 2020
1 parent b98e933 commit ccd8020
Show file tree
Hide file tree
Showing 62 changed files with 2,305 additions and 1,222 deletions.
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.2.0] - 2020-03-13

### Added

- 搜索结果添加关键字高亮
- 位置详情界面添加位置指示

### Changed

- 物品管理主界面将展示过期物品,即将过期,最近添加和最近更新的物品
- 调整 `Webview``IOT` 和博客内嵌至软件

## [0.1.2] - 2020-03-09

### Added
Expand Down Expand Up @@ -35,8 +47,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- 利用 Flutter 编写的第一个可用的智慧家庭客户端

[Unreleased]: https://github.com/he0119/smart-home-flutter/compare/v0.1.2...HEAD
[Unreleased]: https://github.com/he0119/smart-home-flutter/compare/v0.2.0...HEAD

[0.2.0]: https://github.com/he0119/smart-home-flutter/compare/v0.1.2...v0.2.0
[0.1.2]: https://github.com/he0119/smart-home-flutter/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/he0119/smart-home-flutter/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/he0119/smart-home-flutter/releases/tag/v0.1.0
3 changes: 1 addition & 2 deletions lib/blocs/blocs.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export './authentication/authentication_bloc.dart';
export './storage/search_bloc.dart';
export './storage/storage_bloc.dart';
export './snack_bar/snack_bar_bloc.dart';
export './tab/tab_bloc.dart';
26 changes: 26 additions & 0 deletions lib/blocs/snack_bar/snack_bar_bloc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:smart_home/models/models.dart';

part 'snack_bar_event.dart';
part 'snack_bar_state.dart';

class SnackBarBloc extends Bloc<SnackBarEvent, SnackBarState> {
@override
SnackBarState get initialState => SnackBarInitial();

@override
Stream<SnackBarState> mapEventToState(
SnackBarEvent event,
) async* {
if (event is SnackBarChanged) {
yield SnackBarSuccess(
position: event.position,
message: event.message,
type: event.type,
);
}
}
}
20 changes: 20 additions & 0 deletions lib/blocs/snack_bar/snack_bar_event.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
part of 'snack_bar_bloc.dart';

@immutable
abstract class SnackBarEvent {}

class SnackBarChanged extends SnackBarEvent {
final SnackBarPosition position;
final String message;
final MessageType type;

SnackBarChanged({
@required this.position,
@required this.message,
@required this.type,
});

@override
String toString() =>
'SnackBarChanged { message: $message }';
}
22 changes: 22 additions & 0 deletions lib/blocs/snack_bar/snack_bar_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
part of 'snack_bar_bloc.dart';

@immutable
abstract class SnackBarState {}

class SnackBarInitial extends SnackBarState {}

class SnackBarSuccess extends SnackBarState {
final SnackBarPosition position;
final String message;
final MessageType type;

SnackBarSuccess({
@required this.position,
@required this.message,
@required this.type,
});

@override
String toString() =>
'SnackBarSuccess { position: $position, messageType: $type }';
}
146 changes: 146 additions & 0 deletions lib/blocs/storage/item_detail/item_detail_bloc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:smart_home/blocs/blocs.dart';
import 'package:smart_home/models/models.dart';
import 'package:smart_home/repositories/storage_repository.dart';

part 'item_detail_event.dart';
part 'item_detail_state.dart';

class ItemDetailBloc extends Bloc<ItemDetailEvent, ItemDetailState> {
final SnackBarBloc snackBarBloc;

ItemDetailBloc({@required this.snackBarBloc});

@override
ItemDetailState get initialState => ItemDetailInProgress();

@override
Stream<ItemDetailState> mapEventToState(
ItemDetailEvent event,
) async* {
if (event is ItemDetailChanged) {
yield ItemDetailInProgress();
try {
Item results = await storageRepository.item(id: event.itemId);
yield ItemDetailSuccess(item: results);
} catch (e) {
yield ItemDetailError(message: e.message);
}
}
if (event is ItemDetailRefreshed) {
yield ItemDetailInProgress();
try {
Item results = await storageRepository.item(
id: event.itemId,
cache: false,
);
yield ItemDetailSuccess(item: results);
} catch (e) {
yield ItemDetailError(message: e.message);
}
}

if (event is ItemEditStarted) {
yield ItemDetailInProgress();
try {
Item results = await storageRepository.item(id: event.itemId);
yield ItemEditInitial(item: results);
} catch (e) {
yield ItemDetailError(message: e.message);
}
}
if (event is ItemAddStarted) {
yield ItemDetailInProgress();
try {
yield ItemAddInitial(storageId: event.storageId);
} catch (e) {
yield ItemDetailError(message: e.message);
}
}

if (event is ItemUpdated) {
try {
Item item = await storageRepository.updateItem(
id: event.id,
name: event.name,
number: event.number,
storageId: event.storageId,
description: event.description,
price: event.price,
expirationDate: event.expirationDate,
);
yield ItemDetailSuccess(item: item);
snackBarBloc.add(
SnackBarChanged(
position: SnackBarPosition.item,
message: '修改成功',
type: MessageType.info,
),
);
await storageRepository.storage(id: event.storageId, cache: false);
await storageRepository.storage(id: event.oldStorageId, cache: false);
} catch (e) {
snackBarBloc.add(
SnackBarChanged(
position: SnackBarPosition.item,
message: e.message,
type: MessageType.error,
),
);
}
}

if (event is ItemAdded) {
try {
Item item = await storageRepository.addItem(
name: event.name,
number: event.number,
storageId: event.storageId,
description: event.description,
price: event.price,
expirationDate: event.expirationDate,
);
yield ItemAddSuccess(item: item);
snackBarBloc.add(
SnackBarChanged(
position: SnackBarPosition.storage,
message: '${item.name} 添加成功',
type: MessageType.info,
),
);
} catch (e) {
snackBarBloc.add(
SnackBarChanged(
position: SnackBarPosition.item,
message: e.message,
type: MessageType.error,
),
);
}
}

if (event is ItemDeleted) {
try {
await storageRepository.deleteItem(id: event.item.id);
yield ItemDeleteSuccess(item: event.item);
snackBarBloc.add(
SnackBarChanged(
position: SnackBarPosition.storage,
message: '${event.item.name} 删除成功',
type: MessageType.info,
),
);
} catch (e) {
snackBarBloc.add(
SnackBarChanged(
position: SnackBarPosition.item,
message: e.message,
type: MessageType.error,
),
);
}
}
}
}
130 changes: 130 additions & 0 deletions lib/blocs/storage/item_detail/item_detail_event.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
part of 'item_detail_bloc.dart';

abstract class ItemDetailEvent extends Equatable {
const ItemDetailEvent();

@override
List<Object> get props => [];
}

class ItemDetailChanged extends ItemDetailEvent {
final String itemId;

const ItemDetailChanged({@required this.itemId});

@override
List<Object> get props => [itemId];

@override
String toString() => 'ItemChanged { itemId: $itemId }';
}

class ItemDetailRefreshed extends ItemDetailEvent {
final String itemId;

const ItemDetailRefreshed({@required this.itemId});

@override
List<Object> get props => [itemId];

@override
String toString() => 'ItemRefreshed { itemId: $itemId }';
}

class ItemEditStarted extends ItemDetailEvent {
final String itemId;

const ItemEditStarted({@required this.itemId});

@override
List<Object> get props => [itemId];

@override
String toString() => 'ItemEditStarted { itemId: $itemId }';
}

class ItemAddStarted extends ItemDetailEvent {
final String storageId;

const ItemAddStarted({@required this.storageId});

@override
List<Object> get props => [storageId];

@override
String toString() => 'ItemAddStarted { storageId: $storageId }';
}

class ItemUpdated extends ItemDetailEvent {
final String id;
final String name;
final int number;
final String storageId;
final String oldStorageId;
final String description;
final double price;
final DateTime expirationDate;

const ItemUpdated({
@required this.id,
this.name,
this.number,
this.storageId,
this.oldStorageId,
this.description,
this.price,
this.expirationDate,
});

@override
List<Object> get props => [
id,
name,
number,
storageId,
oldStorageId,
description,
price,
expirationDate
];

@override
String toString() => 'ItemUpdated { name: $name }';
}

class ItemAdded extends ItemDetailEvent {
final String name;
final int number;
final String storageId;
final String description;
final double price;
final DateTime expirationDate;

const ItemAdded({
@required this.name,
@required this.number,
@required this.storageId,
this.description,
this.price,
this.expirationDate,
});

@override
List<Object> get props =>
[name, number, storageId, description, price, expirationDate];

@override
String toString() => 'ItemAdded { name: $name }';
}

class ItemDeleted extends ItemDetailEvent {
final Item item;

const ItemDeleted({@required this.item});

@override
List<Object> get props => [item];

@override
String toString() => 'DeleteItem { name: ${item.name} }';
}
Loading

0 comments on commit ccd8020

Please sign in to comment.