Skip to content

Commit

Permalink
marking unread and hidden threads
Browse files Browse the repository at this point in the history
  • Loading branch information
dasmikko committed Feb 28, 2023
1 parent 5f5816b commit e617506
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 1 deletion.
26 changes: 26 additions & 0 deletions lib/controllers/hiddenThreadsController.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:get/get.dart';
import 'package:knocky/helpers/api.dart';
import 'package:knocky/helpers/postsPerPage.dart';
import 'package:knocky/models/v2/alerts.dart';
import 'package:knocky/models/v2/thread.dart';

class HiddenThreadsController extends GetxController {
final isFetching = false.obs;
final RxList<ForumThread> threads = <ForumThread>[].obs;

@override
onInit() {
super.onInit();
}

initState() {
fetch();
}

void fetch() async {
isFetching.value = true;
// Get hidden threads
threads.value = await KnockoutAPI().hiddenThreads();
isFetching.value = false;
}
}
33 changes: 33 additions & 0 deletions lib/helpers/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -513,4 +513,37 @@ class KnockoutAPI {
throw e;
}
}

Future<void> hideThread(int threadId) async {
try {
final response =
await _request(url: 'v2/hidden-threads/${threadId}', type: 'post');
} on DioError catch (e) {
onDioErrorHandler(e);
throw e;
}
}

Future<void> unhideThread(int threadId) async {
try {
final response =
await _request(url: 'v2/hidden-threads/${threadId}', type: 'delete');
} on DioError catch (e) {
onDioErrorHandler(e);
throw e;
}
}

Future<List<ForumThread>> hiddenThreads() async {
try {
final response = await _request(url: 'v2/hidden-threads', type: 'get');

return response.data
.map<ForumThread>((json) => ForumThread.fromJson(json))
.toList();
} on DioError catch (e) {
onDioErrorHandler(e);
throw e;
}
}
}
79 changes: 79 additions & 0 deletions lib/screens/manageHiddenThreads.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:knocky/controllers/hiddenThreadsController.dart';
import 'package:knocky/controllers/subscriptionController.dart';
import 'package:knocky/widgets/KnockoutLoadingIndicator.dart';
import 'package:knocky/widgets/forum/ForumListItem.dart';
import 'package:knocky/widgets/hiddenThreads/hiddenThreadListItem.dart';
import 'package:knocky/widgets/shared/pageSelector.dart';
import 'package:knocky/widgets/shared/threadListItem.dart';
import 'package:knocky/widgets/subforum/subforumListItem.dart';
import 'package:knocky/widgets/subscriptions/subscriptionListItem.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

class ManageHiddenThreadsScreen extends StatefulWidget {
@override
_ManageHiddenThreadsScreenState createState() =>
_ManageHiddenThreadsScreenState();
}

class _ManageHiddenThreadsScreenState extends State<ManageHiddenThreadsScreen> {
final HiddenThreadsController hiddenThreadsController =
Get.put(HiddenThreadsController());

@override
void initState() {
super.initState();
hiddenThreadsController.initState();
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hidden threads'),
),
body: Container(
child: Obx(
() => KnockoutLoadingIndicator(
show: hiddenThreadsController.isFetching.value,
child: RefreshIndicator(
onRefresh: () async => hiddenThreadsController.fetch(),
child: hiddenThreadsController.threads.value.length == 0
? noHiddenThreads()
: threads(),
),
),
),
),
);
}

Widget noHiddenThreads() {
return Center(
child: Text(
"You don't have hidden any threads...",
style: TextStyle(
fontSize: 22,
color: Colors.grey,
),
),
);
}

Widget threads() {
return Container(
padding: EdgeInsets.fromLTRB(0, 4, 0, 4),
child: ScrollablePositionedList.builder(
// ignore: invalid_use_of_protected_member
itemCount: hiddenThreadsController.threads.value.length ?? 0,
itemBuilder: (BuildContext context, int index) {
return HiddenThreadListItem(
threadDetails: hiddenThreadsController.threads.value[index],
);
},
),
);
}
}
8 changes: 8 additions & 0 deletions lib/screens/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:knocky/dialogs/inputDialog.dart';
import 'package:knocky/dialogs/updateAvailableDialog.dart';
import 'package:knocky/helpers/snackbar.dart';
import 'package:knocky/helpers/version.dart';
import 'package:knocky/screens/manageHiddenThreads.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:github/github.dart';

Expand Down Expand Up @@ -158,6 +159,13 @@ class SettingsScreen extends StatelessWidget {
},
),
),
ListTile(
title: Text('Manage hidden threads'),
onTap: () async {
// TODO: Go to screen where you can manage hidden threads
Get.to(() => ManageHiddenThreadsScreen());
},
),

/**
* API
Expand Down
45 changes: 45 additions & 0 deletions lib/widgets/hiddenThreads/hiddenThreadListItem.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';
import 'package:knocky/controllers/hiddenThreadsController.dart';
import 'package:knocky/controllers/subscriptionController.dart';
import 'package:knocky/dialogs/confirmDialog.dart';
import 'package:knocky/helpers/api.dart';
import 'package:knocky/helpers/postsPerPage.dart';
import 'package:knocky/helpers/snackbar.dart';
import 'package:knocky/models/v2/thread.dart';
import 'package:knocky/screens/thread.dart';
import 'package:knocky/widgets/jumpToPageDialog.dart';
import 'package:knocky/widgets/shared/threadListItem.dart';

class HiddenThreadListItem extends ThreadListItem {
final ForumThread? threadDetails;
final HiddenThreadsController hiddenThreadsController =
Get.put(HiddenThreadsController());

HiddenThreadListItem({required this.threadDetails})
: super(threadDetails: threadDetails);

@override
void onTapItem(BuildContext context) async {
// TODO: implement onTapItem
bool confirmResult = await (Get.dialog(ConfirmDialog(
content: "Do you want unhide the thread?",
)));

if (!confirmResult) return;

SnackbarController snackbarController = KnockySnackbar.normal(
"Unhiding thread...",
"Please wait...",
isDismissible: false,
showProgressIndicator: true,
);

await KnockoutAPI().unhideThread(threadDetails!.id!);
snackbarController.close();

KnockySnackbar.success('Thread is now unhidden!');
hiddenThreadsController.fetch();
}
}
4 changes: 3 additions & 1 deletion lib/widgets/shared/threadListItem.dart
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ class ThreadListItem extends StatelessWidget {
),
),
...getTagWidgets(context),
getSubtitle(context)
(threadDetails.user.runtimeType != int)
? getSubtitle(context)
: Container(),
],
),
),
Expand Down
29 changes: 29 additions & 0 deletions lib/widgets/subforum/subforumListItem.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,35 @@ class SubforumListItem extends ThreadListItem {
}
}),
ListTile(
leading: FaIcon(FontAwesomeIcons.eyeSlash),
title: Text('Hide thread'),
onTap: () async {
Get.back();

bool confirmResult = await (Get.dialog(ConfirmDialog(
content:
"Do you want to hide the thread?\n\nYou can find hidden threads in the settings screen.",
)));

if (!confirmResult) return;

SnackbarController snackbarController = KnockySnackbar.normal(
"Adding thread to hidden...",
"Please wait...",
isDismissible: false,
showProgressIndicator: true,
);

await KnockoutAPI().hideThread(threadDetails!.id!);
snackbarController.close();

KnockySnackbar.success("Thread is now hidden");

if (onShouldRefresh != null) {
onShouldRefresh!();
}
}),
ListTile(
leading: FaIcon(FontAwesomeIcons.arrowRotateRight),
title: Text('Go to page'),
onTap: () {
Expand Down

0 comments on commit e617506

Please sign in to comment.