Merge commit '11f9ce371a84a12e5758febc84d6fc73a474fd72' into zhang

hmxc
张萌 4 years ago
commit 59961dd4ce

@ -1,5 +1,7 @@
# akuCommunity
[![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode)
## Getting Started
## Code Contribute

@ -193,6 +193,12 @@ class _Community {
///
String get myEvent => '/user/gambit/myTidings';
///
String get deleteMyEvent => '/user/gambit/falseDelete';
///
String get getEventDetail => '/user/gambit/GambitThemeDetail';
}
class _Upload {

@ -46,7 +46,8 @@ class EventItemModel {
json['likeNames'].forEach((v) {
likeNames.add(new LikeNames.fromJson(v));
});
}
} else
likeNames = [];
if (json['imgUrls'] != null) {
imgUrls = new List<ImgModel>();
json['imgUrls'].forEach((v) {
@ -66,7 +67,8 @@ class EventItemModel {
json['gambitThemeCommentVoList'].forEach((v) {
gambitThemeCommentVoList.add(new GambitThemeCommentVoList.fromJson(v));
});
}
} else
gambitThemeCommentVoList = [];
}
Map<String, dynamic> toJson() {

@ -0,0 +1,25 @@
import 'package:akuCommunity/utils/headers.dart';
import 'package:akuCommunity/widget/bee_scaffold.dart';
import 'package:flutter/material.dart';
class AlarmDetailPage extends StatelessWidget {
const AlarmDetailPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BeeScaffold(
title: '功能说明',
body: ListView(
padding: EdgeInsets.all(32.w),
children: [
'一键报警'.text.size(32.sp).bold.make(),
20.hb,
'点击“呼叫110”后您可以直接拨打本地110。页面中提供了您当前所在位置以便您与警方沟通。GPS信号弱时位置可能存在偏移'
.text
.size(28.sp)
.make(),
],
),
);
}
}

@ -1,18 +1,18 @@
// Flutter imports:
import 'package:akuCommunity/pages/one_alarm/alarm_detail_page.dart';
import 'package:flutter/material.dart';
// Package imports:
import 'package:amap_location_fluttify/amap_location_fluttify.dart';
import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter_beautiful_popup/main.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:velocity_x/velocity_x.dart';
// Project imports:
import 'package:akuCommunity/pages/one_alarm/widget/explain_template.dart';
import 'package:akuCommunity/utils/headers.dart';
import 'package:akuCommunity/widget/bee_scaffold.dart';
@ -41,41 +41,6 @@ class _AlarmPageState extends State<AlarmPage> {
AmapController _amapController;
Location _location;
void showExplain(BuildContext context) {
final popup = BeautifulPopup.customize(
context: context,
build: (options) => ExplainTemplate(options),
);
popup.show(
title: Text(
'功能说明',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 32.sp,
color: Color(0xff15c0ec),
),
),
content: Text(
'点击“呼叫110”后,您可以直接拨打本地110。页面中提供了您当前所在位置,以便您与警方沟通。(GPS信号弱时位置可能存在偏移)',
style: TextStyle(
fontSize: 28.sp,
color: Color(0xff666666),
),
),
actions: [
MaterialButton(
color: Color(0xff15c0ec),
textColor: Colors.white,
shape: RoundedRectangleBorder(
side: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(50))),
child: Text('关闭'),
onPressed: Navigator.of(context).pop,
)
],
close: SizedBox());
}
@override
void initState() {
super.initState();
@ -96,15 +61,9 @@ class _AlarmPageState extends State<AlarmPage> {
return BeeScaffold(
title: '一键报警',
actions: [
InkWell(
onTap: () {
showExplain(context);
},
child: Container(
padding: EdgeInsets.fromLTRB(32.w, 28.w, 32.w, 20.w),
child: '全部已读'.text.black.size(28.sp).make(),
alignment: Alignment.center,
),
MaterialButton(
onPressed: () => Get.to(AlarmDetailPage()),
child: '功能说明'.text.black.size(28.sp).make(),
)
],
body: Stack(

@ -1,93 +0,0 @@
// Dart imports:
import 'dart:ui';
// Flutter imports:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
// Package imports:
import 'package:flutter_beautiful_popup/main.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
// Project imports:
import 'package:akuCommunity/utils/headers.dart';
class ExplainTemplate extends BeautifulPopupTemplate {
final BeautifulPopup options;
ExplainTemplate(this.options) : super(options);
@override
final illustrationPath = 'img/bg/authentication.png';
@override
Color get primaryColor => options.primaryColor ?? Color(0xff15c0ec);
@override
final maxWidth = 400.w;
@override
final maxHeight = 617.w;
@override
final bodyMargin = 0;
@override
get layout {
return [
Positioned(
child: background,
),
Positioned(
top: percentH(32),
child: title,
),
Positioned(
top: percentH(42),
left: percentW(10),
right: percentW(10),
height: percentH(actions == null ? 52 : 38),
child: content,
),
Positioned(
bottom: percentW(8),
left: percentW(8),
right: percentW(8),
child: actions ?? Container(),
),
];
}
}
// class Explain extends StatelessWidget {
// const Explain({Key key}) : super(key: key);
// @override
// Widget build(BuildContext context) {
// return Container(
// color: Colors.white,
// padding: EdgeInsets.only(
// top: 32.w,
// left: 32.w,
// right: 32.w,
// ),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// '一键报警',
// style: TextStyle(
// fontSize: BaseStyle.fontSize32,
// color: ktextPrimary,
// fontWeight: FontWeight.bold,
// ),
// ),
// Container(
// margin: EdgeInsets.only(top: 20.w),
// child: Text(
// '点击“呼叫110”后您可以直接拨打本地110。页面中提供了您当前所在位置以便您与警方沟通。GPS信号弱时位置可能存在偏移',
// style: TextStyle(
// fontSize: BaseStyle.fontSize28,
// color: ktextSubColor,
// ),
// ),
// ),
// ],
// ),
// );
// }
// }

@ -100,6 +100,7 @@ class _BeeListViewState<T> extends State<BeeListView> {
params: _params,
);
_models = widget.convert(_model);
widget.controller.resetLoadState();
setState(() {});
},
firstRefresh: true,

@ -25,6 +25,11 @@ class _CommunityPageState extends State<CommunityPage>
with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {
TabController _tabController;
List<String> _tabs = ['最新', '话题', '我的'];
GlobalKey<TopicCommunityViewState> topicKey =
GlobalKey<TopicCommunityViewState>();
GlobalKey<MyCommunityViewState> myKey = GlobalKey<MyCommunityViewState>();
GlobalKey<NewCommunityViewState> newKey = GlobalKey<NewCommunityViewState>();
@override
void initState() {
super.initState();
@ -47,7 +52,22 @@ class _CommunityPageState extends State<CommunityPage>
),
],
fab: FloatingActionButton(
onPressed: () => Get.to(AddNewEventPage()),
onPressed: () async {
bool result = await Get.to(AddNewEventPage());
if (result == true) {
switch (_tabController.index) {
case 0:
newKey.currentState.refresh();
break;
case 1:
topicKey.currentState.refresh();
break;
case 2:
myKey.currentState.refresh();
break;
}
}
},
heroTag: 'event_add',
child: Icon(Icons.add),
),
@ -64,9 +84,9 @@ class _CommunityPageState extends State<CommunityPage>
),
body: TabBarView(
children: [
NewCommunityView(),
TopicCommunityView(),
MyCommunityView(),
NewCommunityView(key: newKey),
TopicCommunityView(key: topicKey),
MyCommunityView(key: myKey),
],
controller: _tabController,
),

@ -1,21 +1,67 @@
// Flutter imports:
import 'package:akuCommunity/constants/api.dart';
import 'package:akuCommunity/model/community/event_item_model.dart';
import 'package:akuCommunity/ui/community/community_views/widgets/chat_card.dart';
import 'package:akuCommunity/utils/network/base_model.dart';
import 'package:akuCommunity/utils/network/net_util.dart';
import 'package:flutter/material.dart';
// Project imports:
import 'package:akuCommunity/widget/bee_scaffold.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
class EventDetailPage extends StatefulWidget {
EventDetailPage({Key key}) : super(key: key);
final int themeId;
EventDetailPage({
Key key,
@required this.themeId,
}) : super(key: key);
@override
_EventDetailPageState createState() => _EventDetailPageState();
}
class _EventDetailPageState extends State<EventDetailPage> {
EasyRefreshController _refreshController = EasyRefreshController();
EventItemModel _model;
@override
Widget build(BuildContext context) {
return BeeScaffold(
title: '详情',
body: EasyRefresh(
controller: _refreshController,
header: MaterialHeader(),
firstRefresh: true,
onRefresh: () async {
BaseModel model = await NetUtil().get(
API.community.getEventDetail,
params: {'themeId': widget.themeId},
);
_model = EventItemModel.fromJson(model.data);
setState(() {});
},
child: _model == null
? SizedBox()
: ListView(
children: [
ChatCard(
initLike: _model.isLike == 1,
name: _model.createName,
topic: _model.gambitTitle,
headImg: _model.headSculptureImgUrl,
contentImg: _model.imgUrls,
date: _model.date,
id: _model.id,
content: _model.content,
themeId: _model.id,
comments: _model.gambitThemeCommentVoList,
likeNames: _model.likeNames,
hideLine: true,
canTap: false,
),
],
),
),
);
}
}

@ -15,12 +15,17 @@ class MyCommunityView extends StatefulWidget {
MyCommunityView({Key key}) : super(key: key);
@override
_MyCommunityViewState createState() => _MyCommunityViewState();
MyCommunityViewState createState() => MyCommunityViewState();
}
class _MyCommunityViewState extends State<MyCommunityView>
class MyCommunityViewState extends State<MyCommunityView>
with AutomaticKeepAliveClientMixin {
EasyRefreshController _refreshController = EasyRefreshController();
refresh() {
_refreshController?.callRefresh();
}
@override
Widget build(BuildContext context) {
super.build(context);

@ -14,12 +14,17 @@ class NewCommunityView extends StatefulWidget {
NewCommunityView({Key key}) : super(key: key);
@override
_NewCommunityViewState createState() => _NewCommunityViewState();
NewCommunityViewState createState() => NewCommunityViewState();
}
class _NewCommunityViewState extends State<NewCommunityView>
class NewCommunityViewState extends State<NewCommunityView>
with AutomaticKeepAliveClientMixin {
EasyRefreshController _refreshController = EasyRefreshController();
refresh() {
_refreshController?.callRefresh();
}
@override
void dispose() {
_refreshController?.dispose();
@ -49,6 +54,11 @@ class _NewCommunityViewState extends State<NewCommunityView>
headImg: item.headSculptureImgUrl,
themeId: item.id,
initLike: item.isLike == 1,
comments: item.gambitThemeCommentVoList,
likeNames: item.likeNames,
onDelete: () {
_refreshController.callRefresh();
},
);
},
itemCount: items.length,

@ -19,12 +19,15 @@ class TopicCommunityView extends StatefulWidget {
TopicCommunityView({Key key}) : super(key: key);
@override
_TopicCommunityViewState createState() => _TopicCommunityViewState();
TopicCommunityViewState createState() => TopicCommunityViewState();
}
class _TopicCommunityViewState extends State<TopicCommunityView>
class TopicCommunityViewState extends State<TopicCommunityView>
with AutomaticKeepAliveClientMixin {
EasyRefreshController _refreshController = EasyRefreshController();
refresh() {
_refreshController?.callRefresh();
}
_buildItem(CommunityTopicModel model) {
return MaterialButton(

@ -73,6 +73,11 @@ class _TopicDetailPageState extends State<TopicDetailPage> {
contentImg: item.imgUrls,
date: item.date,
id: item.createId,
onDelete: () {
_refreshController.callRefresh();
},
comments: item.gambitThemeCommentVoList,
likeNames: item.likeNames,
);
},
childCount: items.length,

@ -1,4 +1,5 @@
// Flutter imports:
import 'package:akuCommunity/model/community/event_item_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -33,6 +34,14 @@ class ChatCard extends StatefulWidget {
final int themeId;
final VoidCallback onDelete;
final List<GambitThemeCommentVoList> comments;
final List<LikeNames> likeNames;
final bool hideLine;
final bool canTap;
ChatCard({
Key key,
@required this.name,
@ -40,10 +49,15 @@ class ChatCard extends StatefulWidget {
@required this.headImg,
@required this.contentImg,
@required this.date,
this.initLike = false,
@required this.initLike,
@required this.id,
@required this.content,
@required this.themeId,
this.onDelete,
@required this.comments,
this.hideLine = false,
@required this.likeNames,
this.canTap = true,
}) : super(key: key);
@override
@ -136,7 +150,7 @@ class _ChatCardState extends State<ChatCard> {
cancel();
await NetUtil().get(
API.community.like,
params: {'themeId': widget.id},
params: {'themeId': widget.themeId},
showMessage: true,
);
setState(() {
@ -199,6 +213,57 @@ class _ChatCardState extends State<ChatCard> {
});
}
_renderLike() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w),
child: Flex(
direction: Axis.horizontal,
children: [
Icon(Icons.favorite_border_rounded, size: 24.w),
14.wb,
...widget.likeNames
.map((e) => e.name.text.make())
.toList()
.sepWidget(separate: ','.text.make()),
],
),
);
}
_renderComment() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: widget.comments.map((e) {
StringBuffer buffer = StringBuffer();
buffer.write(e.createName);
if (e.parentName != null) buffer.write('回复${e.parentName}');
buffer.write(':${e.content}');
return buffer.toString().text.make();
}).toList(),
);
}
_renderLikeAndComment() {
return Material(
borderRadius: BorderRadius.circular(8.w),
color: Color(0xFFF7F7F7),
child: Padding(
padding: EdgeInsets.all(8.w),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.likeNames.isEmpty ? SizedBox() : _renderLike(),
(widget.likeNames.isNotEmpty && widget.comments.isNotEmpty)
? Divider(height: 1.w, thickness: 1.w)
: SizedBox(),
widget.comments.isEmpty ? SizedBox() : _renderComment(),
],
),
),
);
}
@override
void initState() {
super.initState();
@ -207,21 +272,22 @@ class _ChatCardState extends State<ChatCard> {
@override
Widget build(BuildContext context) {
final userProvider = Provider.of<UserProvider>(context);
return DecoratedBox(
decoration: BoxDecoration(
color: Colors.white,
border: Border(
bottom: BorderSide(
color: Color(0xFFE5E5E5),
color: widget.hideLine ? Colors.transparent : Color(0xFFE5E5E5),
),
),
),
child: MaterialButton(
padding: EdgeInsets.zero,
onPressed: () {
Get.to(EventDetailPage());
},
onPressed: widget.canTap
? () {
Get.to(EventDetailPage(themeId: widget.themeId));
}
: null,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -240,12 +306,12 @@ class _ChatCardState extends State<ChatCard> {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.name.text.size(36.sp).make(),
widget.name.text.black.size(36.sp).make(),
6.hb,
widget.content.text.make(),
widget.content.text.black.make(),
20.hb,
_renderImage(),
widget.topic.isEmpty
widget.topic?.isEmpty ?? true
? SizedBox()
: Chip(
label: '#${widget.topic}'.text.size(22.sp).make(),
@ -259,6 +325,7 @@ class _ChatCardState extends State<ChatCard> {
),
Row(
children: [
64.hb,
BeeDateUtil(widget.date)
.timeAgo
.text
@ -291,7 +358,12 @@ class _ChatCardState extends State<ChatCard> {
));
if (result == true) {
//TODO delete operation
await NetUtil().get(
API.community.deleteMyEvent,
params: {'themeId': widget.themeId},
showMessage: true,
);
if (widget.onDelete != null) widget.onDelete();
}
},
child: '删除'.text.black.size(28.sp).make(),
@ -301,6 +373,7 @@ class _ChatCardState extends State<ChatCard> {
_buildMoreButton(),
],
),
_renderLikeAndComment(),
],
).expand(),
],

@ -28,6 +28,11 @@ class MyEventCard extends StatelessWidget {
BeeDateUtil get beeDate => BeeDateUtil(model.date);
bool get sameDay =>
model.date.year == (preModel?.date?.year ?? 0) &&
model.date.month == (preModel?.date?.month ?? 0) &&
model.date.day == (preModel?.date?.day ?? 0);
Widget title() {
if (beeDate.sameDay) return '今天'.text.size(52.sp).bold.make();
if (beeDate.isYesterday)
@ -65,19 +70,22 @@ class MyEventCard extends StatelessWidget {
width: 200.w,
padding: EdgeInsets.only(left: 32.w),
alignment: Alignment.topLeft,
child: beeDate.sameDay ? SizedBox() : title(),
child: sameDay ? SizedBox() : title(),
),
model.imgUrl.length == 0
? SizedBox(height: 152.w)
: GestureDetector(
onTap: () {
Get.to(
BeeImagePreview.path(path: model.imgUrl.first.url),
BeeImagePreview.path(
path: model.imgUrl.first.url,
tag: API.image(model.imgUrl.first.url),
),
opaque: false,
);
},
child: Hero(
tag: model.imgUrl.first.url,
tag: API.image(model.imgUrl.first.url),
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(

@ -8,11 +8,13 @@ class BeeDateUtil {
bool get sameYear => _now.year == this.date.year;
bool get sameMonth => sameYear && _now.month == this.date.month;
bool get sameDay => sameMonth && _now.day == this.date.day;
bool get isYesterday => (DateTime(_now.year, _now.month, _now.day - 1)
.compareTo(DateTime(this.date.year)) ==
bool get isYesterday =>
(DateTime(_now.year, _now.month, _now.day - 1).compareTo(
DateTime(this.date.year, this.date.month, this.date.day)) ==
0);
bool get isDoubleYesterday => (DateTime(_now.year, _now.month, _now.day - 2)
.compareTo(DateTime(this.date.year)) ==
bool get isDoubleYesterday =>
(DateTime(_now.year, _now.month, _now.day - 2).compareTo(
DateTime(this.date.year, this.date.month, this.date.day)) ==
0);
String get timeAgo {

@ -15,11 +15,12 @@ import 'package:akuCommunity/constants/api.dart';
class BeeImagePreview extends StatefulWidget {
final File file;
final String path;
BeeImagePreview.file({Key key, @required this.file})
final String tag;
BeeImagePreview.file({Key key, @required this.file, this.tag})
: path = null,
super(key: key);
BeeImagePreview.path({Key key, @required this.path})
BeeImagePreview.path({Key key, @required this.path, this.tag})
: file = null,
super(key: key);
@ -31,7 +32,7 @@ class _BeeImagePreviewState extends State<BeeImagePreview> {
Widget get image {
if (widget.file == null)
return Hero(
tag: widget.path,
tag: widget.tag ?? widget.path,
child: FadeInImage.assetNetwork(
placeholder: R.ASSETS_IMAGES_PLACEHOLDER_WEBP,
image: API.image(widget.path),
@ -39,7 +40,7 @@ class _BeeImagePreviewState extends State<BeeImagePreview> {
);
else
return Hero(
tag: widget.file.hashCode,
tag: widget.tag ?? widget.file.hashCode,
child: Image.file(widget.file),
);
}

@ -328,13 +328,6 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.6.1"
flutter_beautiful_popup:
dependency: "direct main"
description:
name: flutter_beautiful_popup
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.5.0"
flutter_blurhash:
dependency: transitive
description:

@ -44,8 +44,6 @@ dependencies:
fluro: ^1.6.3
#滑动卡片
font_awesome_flutter: ^8.8.1
#弹窗
flutter_beautiful_popup: ^1.5.0
#图片预览
photo_view: ^0.10.2
#图片缓存

Loading…
Cancel
Save