Skip to content

Commit cbedd51

Browse files
committed
fix(html): recognize user credit and permission page url
1 parent fce3d26 commit cbedd51

File tree

5 files changed

+42
-2
lines changed

5 files changed

+42
-2
lines changed

lib/exceptions/exceptions.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,11 @@ final class ThreadPublishLocationNotFoundException extends AppException
372372
final class NotificationUserNotFound extends AppException
373373
with NotificationUserNotFoundMappable {}
374374

375+
/// Notification not found in bloc.
376+
@MappableClass()
377+
final class NotificationNotFound extends AppException
378+
with NotificationNotFoundMappable {}
379+
375380
/// Cookie not found in storage when doing auto checkin for user [userInfo].
376381
///
377382
/// Means a checkin failure.

lib/extensions/string.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,36 @@ extension ParseUrl on String {
204204
String? uriQueryParameter(String name) {
205205
return Uri.parse(this).queryParameters[name];
206206
}
207+
208+
/// Check a string is pattern of user space url.
209+
///
210+
/// A string is a valid user space url ONLY if
211+
///
212+
/// 1. Is a valid url.
213+
/// 2. In query parameters, 'mod' == 'space'.
214+
/// 3. In query parameters, contains key 'uid' or 'username'. (email ignored).
215+
/// 4. In query parameters, value of 'ac' is neither 'usergroup' nor 'credit'.
216+
bool get isUserSpaceUrl {
217+
final args = Uri.tryParse(this)?.queryParameters;
218+
if (args == null) {
219+
return false;
220+
}
221+
222+
if (args['mod'] != 'space') {
223+
return false;
224+
}
225+
226+
if (args['uid'] == null && args['username'] == null) {
227+
return false;
228+
}
229+
230+
final ac = args['ac'];
231+
if (ac == 'usergroup' || ac == 'credit') {
232+
return false;
233+
}
234+
235+
return true;
236+
}
207237
}
208238

209239
/// Extension on [String] that enhances modification.

lib/features/notification/bloc/notification_bloc.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:bloc/bloc.dart';
22
import 'package:dart_mappable/dart_mappable.dart';
33
import 'package:fpdart/fpdart.dart';
4+
import 'package:tsdm_client/exceptions/exceptions.dart';
45
import 'package:tsdm_client/extensions/date_time.dart';
56
import 'package:tsdm_client/extensions/fp.dart';
67
import 'package:tsdm_client/extensions/string.dart';
@@ -400,6 +401,10 @@ class NotificationBloc extends Bloc<NotificationEvent, NotificationState>
400401
final task = switch (recordMark) {
401402
RecordMarkNotice(:final uid, :final nid, alreadyRead: final read) => () {
402403
final targetIndex = state.noticeList.indexWhere((e) => e.id == nid);
404+
if (targetIndex < 0) {
405+
// target not found.
406+
return AsyncVoidEither(() async => left(NotificationNotFound()));
407+
}
403408
final target = state.noticeList[targetIndex];
404409
final list = state.noticeList.toList();
405410
list[targetIndex] = target.copyWith(alreadyRead: read);

lib/utils/html/html_muncher.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@ final class _Muncher with LoggerMixin {
846846
return ret;
847847
}
848848
final Widget content;
849-
if (url.contains('mod=space') && !element.innerText.contains('@')) {
849+
if (url.isUserSpaceUrl && !element.innerText.contains('@')) {
850850
content = Text(
851851
'@',
852852
style: TextStyle(

pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2078,4 +2078,4 @@ packages:
20782078
version: "3.1.3"
20792079
sdks:
20802080
dart: ">=3.6.0 <4.0.0"
2081-
flutter: ">=3.27.0"
2081+
flutter: ">=3.27.1"

0 commit comments

Comments
 (0)