Skip to content

Commit 0be4261

Browse files
Update folder
1 parent 65a21bc commit 0be4261

File tree

9 files changed

+998
-296
lines changed

9 files changed

+998
-296
lines changed

lib/Api/post_api.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,25 @@ class PostApi {
3838
);
3939
}
4040

41+
static Future subscribeOrUnSubscribe({
42+
int postId = 0,
43+
int blogId = 0,
44+
List<String> folderIds = const [],
45+
}) async {
46+
var data = {
47+
"postid": postId,
48+
"blogid": blogId,
49+
"method": "updateSubscribe",
50+
};
51+
if (folderIds.isNotEmpty) {
52+
data['folderIds'] = folderIds.join(",");
53+
}
54+
return RequestUtil.post(
55+
"/v2.0/subscribePost.api",
56+
data: data,
57+
);
58+
}
59+
4160
static Future getDetail({
4261
required int postId,
4362
required int blogId,

lib/Api/user_api.dart

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:dio/dio.dart';
22
import 'package:loftify/Utils/enums.dart';
33
import 'package:loftify/Utils/request_header_util.dart';
44

5+
import '../Models/favorites_response.dart';
56
import '../Utils/request_util.dart';
67
import '../Utils/utils.dart';
78

@@ -136,6 +137,19 @@ class UserApi {
136137
);
137138
}
138139

140+
static Future getSubscribeFolderList({
141+
int postId = 0,
142+
int blogId = 0,
143+
}) async {
144+
return RequestUtil.get(
145+
"/newapi/subFolder/getSubscribeFolders.json",
146+
params: {
147+
"postId": "$postId",
148+
"blogId": blogId,
149+
},
150+
);
151+
}
152+
139153
static Future getFavoriteFolderDetail({
140154
int offset = 0,
141155
int folderId = 0,
@@ -151,6 +165,51 @@ class UserApi {
151165
);
152166
}
153167

168+
static Future createFolder({
169+
required String name,
170+
}) async {
171+
return RequestUtil.post(
172+
"/newapi/subFolder/modifyFolder.json",
173+
params: {
174+
"coverUrl": "",
175+
"id": 0,
176+
"status": 0,
177+
"tags": "",
178+
"description": "",
179+
"name": name,
180+
"themeIds": "",
181+
},
182+
);
183+
}
184+
185+
static Future deleteFolder({
186+
required int folderId,
187+
}) async {
188+
return RequestUtil.post(
189+
"/newapi/subFolder/delFolder.json",
190+
params: {
191+
"id": "$folderId",
192+
},
193+
);
194+
}
195+
196+
static Future editFolder({
197+
required FavoriteFolder folder,
198+
}) async {
199+
return RequestUtil.post(
200+
"/newapi/subFolder/modifyFolder.json",
201+
params: {
202+
"coverUrl": folder.coverUrl,
203+
"id": folder.id,
204+
"status": folder.status,
205+
"tags": folder.tags,
206+
"description": "",
207+
"name": folder.name,
208+
"themeIds": folder.themes,
209+
},
210+
);
211+
}
212+
154213
static Future getHistoryList({
155214
int offset = 0,
156215
required String blogDomain,

lib/Models/post_detail_response.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class PostDetailData {
1717
bool? subscribed;
1818
int? opTime;
1919

20+
bool get subscribedNotNull => subscribed == true;
21+
2022
PostDetailData({
2123
this.followed,
2224
this.liked,

lib/Screens/Info/favorite_folder_detail_screen.dart

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -241,21 +241,21 @@ class _FavoriteFolderDetailScreenState extends State<FavoriteFolderDetailScreen>
241241
showBack: true,
242242
title: _favoriteFolder?.name ?? "收藏夹详情",
243243
actions: [
244-
ItemBuilder.buildIconButton(
245-
context: context,
246-
icon: Icon(icon, color: Theme.of(context).iconTheme.color),
247-
onTap: () {
248-
_layoutMode = FavoriteFolderDetailLayoutMode.values[
249-
(_layoutMode.index + 1) %
250-
FavoriteFolderDetailLayoutMode.values.length];
251-
setState(() {});
252-
}),
253-
const SizedBox(width: 5),
254-
ItemBuilder.buildIconButton(
255-
context: context,
256-
icon: Icon(Icons.more_vert_rounded,
257-
color: Theme.of(context).iconTheme.color),
258-
onTap: () {}),
244+
// ItemBuilder.buildIconButton(
245+
// context: context,
246+
// icon: Icon(icon, color: Theme.of(context).iconTheme.color),
247+
// onTap: () {
248+
// _layoutMode = FavoriteFolderDetailLayoutMode.values[
249+
// (_layoutMode.index + 1) %
250+
// FavoriteFolderDetailLayoutMode.values.length];
251+
// setState(() {});
252+
// }),
253+
// const SizedBox(width: 5),
254+
// ItemBuilder.buildIconButton(
255+
// context: context,
256+
// icon: Icon(Icons.more_vert_rounded,
257+
// color: Theme.of(context).iconTheme.color),
258+
// onTap: () {}),
259259
const SizedBox(width: 5),
260260
],
261261
);

lib/Screens/Info/favorite_folder_list_screen.dart

Lines changed: 132 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ import 'package:loftify/Api/user_api.dart';
66
import 'package:loftify/Models/favorites_response.dart';
77
import 'package:loftify/Resources/theme.dart';
88
import 'package:loftify/Screens/Info/favorite_folder_detail_screen.dart';
9+
import 'package:loftify/Widgets/Dialog/dialog_builder.dart';
10+
import 'package:waterfall_flow/waterfall_flow.dart';
911

12+
import '../../Utils/constant.dart';
1013
import '../../Utils/ilogger.dart';
1114
import '../../Utils/itoast.dart';
15+
import '../../Utils/responsive_util.dart';
1216
import '../../Utils/route_util.dart';
1317
import '../../Utils/utils.dart';
18+
import '../../Widgets/BottomSheet/bottom_sheet_builder.dart';
19+
import '../../Widgets/BottomSheet/input_bottom_sheet.dart';
1420
import '../../Widgets/General/EasyRefresh/easy_refresh.dart';
1521
import '../../Widgets/Item/item_builder.dart';
1622

@@ -92,21 +98,32 @@ class _FavoriteFolderListScreenState extends State<FavoriteFolderListScreen>
9298
return Scaffold(
9399
backgroundColor: MyTheme.getBackground(context),
94100
appBar: _buildAppBar(),
95-
body: EasyRefresh(
96-
refreshOnStart: true,
97-
controller: _refreshController,
98-
onRefresh: _onRefresh,
99-
onLoad: _onLoad,
100-
triggerAxis: Axis.vertical,
101-
child: _buildBody(),
101+
body: Stack(
102+
children: [
103+
EasyRefresh(
104+
refreshOnStart: true,
105+
controller: _refreshController,
106+
onRefresh: _onRefresh,
107+
onLoad: _onLoad,
108+
triggerAxis: Axis.vertical,
109+
child: _buildBody(),
110+
),
111+
Positioned(
112+
right: ResponsiveUtil.isLandscape() ? 16 : 12,
113+
bottom: ResponsiveUtil.isLandscape() ? 16 : 76,
114+
child: _buildFloatingButtons(),
115+
),
116+
],
102117
),
103118
);
104119
}
105120

106121
Widget _buildBody() {
107-
return ListView(
108-
cacheExtent: 9999,
109-
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
122+
return WaterfallFlow.extent(
123+
maxCrossAxisExtent: 800,
124+
mainAxisSpacing: 12,
125+
crossAxisSpacing: 12,
126+
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
110127
children: List.generate(_favoriteFolderList.length, (index) {
111128
return _buildFolderItem(
112129
context,
@@ -116,7 +133,7 @@ class _FavoriteFolderListScreenState extends State<FavoriteFolderListScreen>
116133
);
117134
}
118135

119-
static Widget _buildFolderItem(BuildContext context, FavoriteFolder item) {
136+
Widget _buildFolderItem(BuildContext context, FavoriteFolder item) {
120137
return ItemBuilder.buildClickItem(
121138
GestureDetector(
122139
onTap: () {
@@ -187,32 +204,126 @@ class _FavoriteFolderListScreenState extends State<FavoriteFolderListScreen>
187204
),
188205
),
189206
),
207+
ItemBuilder.buildIconButton(
208+
context: context,
209+
icon: const Icon(Icons.edit_note_rounded),
210+
onTap: () {
211+
BottomSheetBuilder.showBottomSheet(
212+
context,
213+
(sheetContext) => InputBottomSheet(
214+
buttonText: "确认",
215+
title: "编辑收藏夹名称",
216+
hint: "输入收藏夹名称",
217+
text: item.name ?? "",
218+
onConfirm: (text) {
219+
var tmp = item;
220+
tmp.name = text;
221+
UserApi.editFolder(folder: tmp).then((value) {
222+
if (value['code'] == 0) {
223+
IToast.showTop("编辑成功");
224+
item.name = text;
225+
setState(() {});
226+
} else {
227+
IToast.showTop(value['msg']);
228+
}
229+
});
230+
},
231+
),
232+
preferMinWidth: 400,
233+
responsive: true,
234+
);
235+
},
236+
),
237+
if (item.isDefault != 1)
238+
ItemBuilder.buildIconButton(
239+
context: context,
240+
icon: const Icon(Icons.delete_outline_rounded,
241+
color: Colors.red),
242+
onTap: () {
243+
DialogBuilder.showConfirmDialog(
244+
context,
245+
title: "删除收藏夹",
246+
message: "确定删除收藏夹 ${item.name} ?删除后,其中的文章也将取消收藏",
247+
messageTextAlign: TextAlign.center,
248+
onTapConfirm: () async {
249+
UserApi.deleteFolder(folderId: item.id ?? 0)
250+
.then((value) {
251+
if (value['code'] == 0) {
252+
IToast.showTop("删除成功");
253+
_refreshController.callRefresh();
254+
} else {
255+
IToast.showTop(value['msg']);
256+
}
257+
});
258+
},
259+
);
260+
},
261+
),
190262
],
191263
),
192264
),
193265
),
194266
);
195267
}
196268

269+
handleAdd() {
270+
BottomSheetBuilder.showBottomSheet(
271+
context,
272+
(sheetContext) => InputBottomSheet(
273+
buttonText: "确认",
274+
title: "新建收藏夹",
275+
hint: "输入收藏夹名称",
276+
text: "",
277+
onConfirm: (text) {
278+
UserApi.createFolder(name: text).then((value) {
279+
if (value['code'] == 0) {
280+
IToast.showTop("创建成功");
281+
_refreshController.callRefresh();
282+
} else {
283+
IToast.showTop(value['msg']);
284+
}
285+
});
286+
},
287+
),
288+
preferMinWidth: 400,
289+
responsive: true,
290+
);
291+
}
292+
197293
PreferredSizeWidget _buildAppBar() {
198294
return ItemBuilder.buildDesktopAppBar(
199295
context: context,
200296
showBack: true,
201297
title: "我的收藏",
202298
actions: [
299+
// ItemBuilder.buildIconButton(
300+
// context: context,
301+
// icon: Icon(Icons.search_rounded,
302+
// color: Theme.of(context).iconTheme.color),
303+
// onTap: () {}),
304+
// const SizedBox(width: 5),
203305
ItemBuilder.buildIconButton(
204-
context: context,
205-
icon: Icon(Icons.search_rounded,
206-
color: Theme.of(context).iconTheme.color),
207-
onTap: () {}),
208-
const SizedBox(width: 5),
209-
ItemBuilder.buildIconButton(
210-
context: context,
211-
icon: Icon(Icons.more_vert_rounded,
212-
color: Theme.of(context).iconTheme.color),
213-
onTap: () {}),
306+
context: context,
307+
icon:
308+
Icon(Icons.add_rounded, color: Theme.of(context).iconTheme.color),
309+
onTap: handleAdd,
310+
),
214311
const SizedBox(width: 5),
215312
],
216313
);
217314
}
315+
316+
_buildFloatingButtons() {
317+
return ResponsiveUtil.isLandscape()
318+
? Column(
319+
children: [
320+
ItemBuilder.buildShadowIconButton(
321+
context: context,
322+
icon: const Icon(Icons.add_rounded),
323+
onTap: handleAdd,
324+
),
325+
],
326+
)
327+
: emptyWidget;
328+
}
218329
}

0 commit comments

Comments
 (0)