From 1f5b5e441b88741552ac4608d17613dd8f852371 Mon Sep 17 00:00:00 2001
From: Pranav <122373207+pranavkonidena@users.noreply.github.com>
Date: Tue, 27 Feb 2024 11:28:41 +0530
Subject: [PATCH] Network Interceptor for noticeboard mobile (#35)
* Bump up IOS version to 12 , added network interceptor in list_notices screen
* Added network interceptor to all reqd widgets
* Add Pranav to contributors.md
* Added root context to the stream so that it is always mounted
* Fix flutter analyze, removed deprecated willpopscope
* Added dynamic fetch when back online
All changes are as follows:
I have updated the web view flutter package to 4.7.0 and upgraded
flutter version to 3.19 because reloading the webview requires a webview
controller, also added another stream for this purpose
* Added EOF in enums, removed build files
---
CONTRIBUTORS.md | 3 +-
noticeboard/ios/.gitignore | 1 +
.../ios/Flutter/AppFrameworkInfo.plist | 2 +-
noticeboard/ios/Podfile | 2 +-
noticeboard/ios/Podfile.lock | 14 +--
.../ios/Runner.xcodeproj/project.pbxproj | 14 +--
.../xcshareddata/xcschemes/Runner.xcscheme | 2 +-
noticeboard/ios/Runner/Runner.entitlements | 5 ++
.../lib/bloc/connectivity_status_bloc.dart | 49 ++++++++++
noticeboard/lib/bloc/list_notices_bloc.dart | 1 -
noticeboard/lib/bloc/notice_detail_bloc.dart | 12 +++
.../lib/enum/connectivity_status_enum.dart | 4 +
noticeboard/lib/enum/current_widget_enum.dart | 4 +
noticeboard/lib/global/global_functions.dart | 28 ++++++
noticeboard/lib/main.dart | 3 +
noticeboard/lib/routes/routing.dart | 1 -
.../lib/screens/bottom_navigation.dart | 20 ++++-
noticeboard/lib/screens/filters.dart | 2 +-
noticeboard/lib/screens/launching.dart | 1 -
noticeboard/lib/screens/list_notices.dart | 19 +++-
noticeboard/lib/screens/notice_detail.dart | 89 ++++++++++++-------
noticeboard/lib/screens/profile.dart | 16 +++-
noticeboard/pubspec.yaml | 2 +-
23 files changed, 230 insertions(+), 64 deletions(-)
create mode 100644 noticeboard/ios/Runner/Runner.entitlements
create mode 100644 noticeboard/lib/bloc/connectivity_status_bloc.dart
create mode 100644 noticeboard/lib/bloc/notice_detail_bloc.dart
create mode 100644 noticeboard/lib/enum/connectivity_status_enum.dart
create mode 100644 noticeboard/lib/enum/current_widget_enum.dart
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 1eded78..490ca1a 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -1,3 +1,4 @@
- [@Sparsh1212](https://github.com/Sparsh1212)
- [@just-ary27](https://github.com/just-ary27)
-- [@kmrinal19](https://github.com/kmrinal19)
\ No newline at end of file
+- [@kmrinal19](https://github.com/kmrinal19)
+- [@pranavkonidena](https://github.com/pranavkonidena)
\ No newline at end of file
diff --git a/noticeboard/ios/.gitignore b/noticeboard/ios/.gitignore
index e96ef60..9a29ebd 100644
--- a/noticeboard/ios/.gitignore
+++ b/noticeboard/ios/.gitignore
@@ -24,6 +24,7 @@ Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
+build/
# Exceptions to above rules.
!default.mode1v3
diff --git a/noticeboard/ios/Flutter/AppFrameworkInfo.plist b/noticeboard/ios/Flutter/AppFrameworkInfo.plist
index f2872cf..8c6e561 100644
--- a/noticeboard/ios/Flutter/AppFrameworkInfo.plist
+++ b/noticeboard/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 9.0
+ 12.0
diff --git a/noticeboard/ios/Podfile b/noticeboard/ios/Podfile
index 52cd522..e0da1a9 100644
--- a/noticeboard/ios/Podfile
+++ b/noticeboard/ios/Podfile
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
- platform :ios, '10.0'
+ platform :ios, '12.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
diff --git a/noticeboard/ios/Podfile.lock b/noticeboard/ios/Podfile.lock
index 161b93f..34c0a76 100644
--- a/noticeboard/ios/Podfile.lock
+++ b/noticeboard/ios/Podfile.lock
@@ -7,7 +7,7 @@ PODS:
- firebase_core (2.24.2):
- Firebase/CoreOnly (= 10.18.0)
- Flutter
- - firebase_messaging (14.7.9):
+ - firebase_messaging (14.7.10):
- Firebase/Messaging (= 10.18.0)
- firebase_core
- Flutter
@@ -119,23 +119,23 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
Firebase: 414ad272f8d02dfbf12662a9d43f4bba9bec2a06
firebase_core: 0af4a2b24f62071f9bf283691c0ee41556dcb3f5
- firebase_messaging: 875385354f623750aa03204a028d640108bc3412
+ firebase_messaging: 90e8a6db84b6e1e876cebce4f30f01dc495e7014
FirebaseCore: 2322423314d92f946219c8791674d2f3345b598f
FirebaseCoreInternal: b444828ea7cfd594fca83046b95db98a2be4f290
FirebaseInstallations: 033d199474164db20c8350736842a94fe717b960
FirebaseMessaging: 9bc34a98d2e0237e1b121915120d4d48ddcf301e
- Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
+ Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
GoogleDataTransport: 57c22343ab29bc686febbf7cbb13bad167c2d8fe
GoogleUtilities: 0759d1a57ebb953965c2dfe0ba4c82e95ccc2e34
nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5
- path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
+ path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4
share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
- url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b
- webview_flutter_wkwebview: b7e70ef1ddded7e69c796c7390ee74180182971f
+ url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
+ webview_flutter_wkwebview: be0f0d33777f1bfd0c9fdcb594786704dbf65f36
-PODFILE CHECKSUM: f3c6bbf2cd440a5be9eae241d089fc1e5c9e4ade
+PODFILE CHECKSUM: 7b33e402635c950b38d380dc47108a3f46f265c2
COCOAPODS: 1.14.3
diff --git a/noticeboard/ios/Runner.xcodeproj/project.pbxproj b/noticeboard/ios/Runner.xcodeproj/project.pbxproj
index a8ef9ee..7999777 100644
--- a/noticeboard/ios/Runner.xcodeproj/project.pbxproj
+++ b/noticeboard/ios/Runner.xcodeproj/project.pbxproj
@@ -158,7 +158,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1430;
+ LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@@ -346,7 +346,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
ONLY_ACTIVE_ARCH = NO;
SDKROOT = iphoneos;
@@ -372,7 +372,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Noticeboard;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -436,7 +436,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = NO;
SDKROOT = iphoneos;
@@ -485,7 +485,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -512,7 +512,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Noticeboard;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -546,7 +546,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Noticeboard;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
diff --git a/noticeboard/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/noticeboard/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index a6b826d..5e31d3d 100644
--- a/noticeboard/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/noticeboard/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
+
+
+
+
diff --git a/noticeboard/lib/bloc/connectivity_status_bloc.dart b/noticeboard/lib/bloc/connectivity_status_bloc.dart
new file mode 100644
index 0000000..e23684b
--- /dev/null
+++ b/noticeboard/lib/bloc/connectivity_status_bloc.dart
@@ -0,0 +1,49 @@
+import 'dart:async';
+import 'package:flutter/material.dart';
+import 'package:noticeboard/bloc/notice_detail_bloc.dart';
+import 'package:noticeboard/enum/connectivity_status_enum.dart';
+import 'package:noticeboard/enum/current_widget_enum.dart';
+
+class ConnectivityStatusBloc {
+ late BuildContext context;
+ late CurrentWidget currentWidget;
+ final _eventController = StreamController.broadcast();
+ StreamSink get eventSink => _eventController.sink;
+ Stream get _eventStream => _eventController.stream;
+ ConnectivityStatus previousResult = ConnectivityStatus.connected;
+
+ static final ConnectivityStatusBloc _connectivityStatusBloc =
+ ConnectivityStatusBloc._();
+
+ final networkSnackBar =
+ const SnackBar(content: Text("Please check your internet connection!"));
+ final backOnlineSnackbar = const SnackBar(content: Text("Back online!"));
+
+ factory ConnectivityStatusBloc() => _connectivityStatusBloc;
+ final NoticeDetailBloc _noticeDetailBloc = NoticeDetailBloc();
+
+ ConnectivityStatusBloc._() {
+ _eventStream.listen((connectivityEvent) {
+ if (connectivityEvent == ConnectivityStatus.notConnected &&
+ previousResult == ConnectivityStatus.connected &&
+ context.mounted) {
+ ScaffoldMessenger.of(context).showSnackBar(networkSnackBar);
+ } else if (connectivityEvent == ConnectivityStatus.connected &&
+ previousResult == ConnectivityStatus.notConnected) {
+ ScaffoldMessenger.of(context).showSnackBar(backOnlineSnackbar);
+ if (currentWidget == CurrentWidget.noticeDetail) {
+ // Add an event in the sink so that notice detail webview can be refetched
+ _noticeDetailBloc.eventSink.add(CurrentWidget.noticeDetail);
+ } else {
+ // User is on list of notices , refetch them
+ _noticeDetailBloc.eventSink.add(CurrentWidget.listNotices);
+ }
+ }
+ previousResult = connectivityEvent;
+ });
+ }
+
+ void disposeStream() {
+ _eventController.close();
+ }
+}
diff --git a/noticeboard/lib/bloc/list_notices_bloc.dart b/noticeboard/lib/bloc/list_notices_bloc.dart
index 7bd82e7..3194a88 100644
--- a/noticeboard/lib/bloc/list_notices_bloc.dart
+++ b/noticeboard/lib/bloc/list_notices_bloc.dart
@@ -314,7 +314,6 @@ class ListNoticesBloc {
DynamicFetch.fetchInstituteNotices)
filterResult.endpoint =
'api/noticeboard/institute_notices/?start=${filterResult.startDate}&end=${filterResult.endDate}';
- // TODO: Add the if condition for Institute Notices case
}
PaginatedInfo paginatedInfo = await _listNoticesRepository
.fetchFilteredNotices(filterResult.endpoint!, page);
diff --git a/noticeboard/lib/bloc/notice_detail_bloc.dart b/noticeboard/lib/bloc/notice_detail_bloc.dart
new file mode 100644
index 0000000..eb2ed12
--- /dev/null
+++ b/noticeboard/lib/bloc/notice_detail_bloc.dart
@@ -0,0 +1,12 @@
+import 'dart:async';
+
+import 'package:noticeboard/enum/current_widget_enum.dart';
+
+class NoticeDetailBloc {
+ final _eventController = StreamController.broadcast();
+ StreamSink get eventSink => _eventController.sink;
+ Stream get eventStream => _eventController.stream;
+ static final NoticeDetailBloc _noticeDetailBloc = NoticeDetailBloc._();
+ factory NoticeDetailBloc() => _noticeDetailBloc;
+ NoticeDetailBloc._();
+}
diff --git a/noticeboard/lib/enum/connectivity_status_enum.dart b/noticeboard/lib/enum/connectivity_status_enum.dart
new file mode 100644
index 0000000..8802e2f
--- /dev/null
+++ b/noticeboard/lib/enum/connectivity_status_enum.dart
@@ -0,0 +1,4 @@
+enum ConnectivityStatus{
+ connected ,
+ notConnected
+}
diff --git a/noticeboard/lib/enum/current_widget_enum.dart b/noticeboard/lib/enum/current_widget_enum.dart
new file mode 100644
index 0000000..12268fd
--- /dev/null
+++ b/noticeboard/lib/enum/current_widget_enum.dart
@@ -0,0 +1,4 @@
+enum CurrentWidget {
+ listNotices,
+ noticeDetail
+}
diff --git a/noticeboard/lib/global/global_functions.dart b/noticeboard/lib/global/global_functions.dart
index fdec8b1..00cb984 100644
--- a/noticeboard/lib/global/global_functions.dart
+++ b/noticeboard/lib/global/global_functions.dart
@@ -1,6 +1,11 @@
+import 'dart:async';
+import 'dart:io';
+
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
+import 'package:noticeboard/bloc/connectivity_status_bloc.dart';
+import 'package:noticeboard/enum/connectivity_status_enum.dart';
import 'package:noticeboard/global/global_constants.dart';
import 'package:shimmer/shimmer.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
@@ -206,3 +211,26 @@ void showGenericError() {
content: Text("Error!"),
));
}
+
+Future checkConnectivityStatus() async {
+ try {
+ final result = await InternetAddress.lookup("www.example.com");
+ if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
+ return ConnectivityStatus.connected;
+ } else {
+ return ConnectivityStatus.notConnected;
+ }
+ } catch (e) {
+ return ConnectivityStatus.notConnected;
+ }
+}
+
+Timer addConnectivityStatusToSink() {
+ final ConnectivityStatusBloc _connectivityStatusBloc =
+ ConnectivityStatusBloc();
+ Timer _timer = Timer.periodic(Duration(seconds: 15), (timer) async {
+ ConnectivityStatus connectivityStatus = await checkConnectivityStatus();
+ _connectivityStatusBloc.eventSink.add(connectivityStatus);
+ });
+ return _timer;
+}
diff --git a/noticeboard/lib/main.dart b/noticeboard/lib/main.dart
index 6d9aee2..85e3a58 100644
--- a/noticeboard/lib/main.dart
+++ b/noticeboard/lib/main.dart
@@ -1,5 +1,6 @@
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
+import 'package:noticeboard/bloc/connectivity_status_bloc.dart';
import './routes/routing_constants.dart';
import './routes/routing.dart';
import 'global/global_constants.dart';
@@ -19,6 +20,8 @@ class _MyAppState extends State {
// This widget is the root of your application.
@override
void initState() {
+ ConnectivityStatusBloc _connectivityStatusBloc = ConnectivityStatusBloc();
+ _connectivityStatusBloc.context = context;
super.initState();
}
diff --git a/noticeboard/lib/routes/routing.dart b/noticeboard/lib/routes/routing.dart
index 7248c2c..a90246e 100644
--- a/noticeboard/lib/routes/routing.dart
+++ b/noticeboard/lib/routes/routing.dart
@@ -6,7 +6,6 @@ import './routing_constants.dart';
import '../screens/login.dart';
import '../screens/list_notices.dart';
import '../screens/launching.dart';
-import '../models/notice_intro.dart';
import '../screens/notice_detail.dart';
class MyRouter {
diff --git a/noticeboard/lib/screens/bottom_navigation.dart b/noticeboard/lib/screens/bottom_navigation.dart
index b3cae16..bc62cdc 100644
--- a/noticeboard/lib/screens/bottom_navigation.dart
+++ b/noticeboard/lib/screens/bottom_navigation.dart
@@ -1,6 +1,8 @@
+import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
+import 'package:noticeboard/global/global_functions.dart';
import '../enum/dynamic_fetch_enum.dart';
import '../screens/list_notices.dart';
import '../models/notice_intro.dart';
@@ -14,6 +16,7 @@ class MyBottomNavigationBar extends StatefulWidget {
class _MyBottomNavigationBarState extends State {
BottomNavigatorBloc _bottomNavigatorBloc = BottomNavigatorBloc();
+ late Timer _timer;
final widgetOptions = [
ListNotices(
listNoticeMetaData: ListNoticeMetaData(
@@ -37,24 +40,33 @@ class _MyBottomNavigationBarState extends State {
_bottomNavigatorBloc.indexSink.add(index);
}
+ @override
+ void initState() {
+ _timer = addConnectivityStatusToSink();
+ super.initState();
+ }
+
@override
void dispose() {
_bottomNavigatorBloc.disposeStreams();
+ if (_timer.isActive) _timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
- return WillPopScope(
- onWillPop: () async {
+ return PopScope(
+ canPop: false,
+ onPopInvoked: (didPop) async {
+ if (didPop) {
+ return;
+ }
await Future.delayed(
Duration(milliseconds: 500),
);
if (Platform.isAndroid) {
SystemNavigator.pop();
- return true;
} else {
- return false;
}
},
child: StreamBuilder(
diff --git a/noticeboard/lib/screens/filters.dart b/noticeboard/lib/screens/filters.dart
index c598264..72fefdd 100644
--- a/noticeboard/lib/screens/filters.dart
+++ b/noticeboard/lib/screens/filters.dart
@@ -55,7 +55,7 @@ class _FiltersState extends State {
child: GestureDetector(
onTap: () {
_filtersBloc.eventSink.add(FilterEvents.resetGlobalSlug);
- WidgetsBinding.instance!.addPostFrameCallback((time) {
+ WidgetsBinding.instance.addPostFrameCallback((time) {
onFilterClear();
});
},
diff --git a/noticeboard/lib/screens/launching.dart b/noticeboard/lib/screens/launching.dart
index 7a858d9..3f434ce 100644
--- a/noticeboard/lib/screens/launching.dart
+++ b/noticeboard/lib/screens/launching.dart
@@ -12,7 +12,6 @@ import '../models/notice_intro.dart';
import '../services/api_service/api_service.dart';
import '../services/auth/auth_repository.dart';
import '../global/global_functions.dart';
-import '../styles/launching_constants.dart';
import '../styles/login_constants.dart';
class Launcher extends StatefulWidget {
diff --git a/noticeboard/lib/screens/list_notices.dart b/noticeboard/lib/screens/list_notices.dart
index ccd2b05..56005c5 100644
--- a/noticeboard/lib/screens/list_notices.dart
+++ b/noticeboard/lib/screens/list_notices.dart
@@ -1,6 +1,11 @@
+import 'dart:async';
+
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:focused_menu/modals.dart';
+import 'package:noticeboard/bloc/connectivity_status_bloc.dart';
+import 'package:noticeboard/bloc/notice_detail_bloc.dart';
+import 'package:noticeboard/enum/current_widget_enum.dart';
import 'package:noticeboard/models/filters_list.dart';
import 'package:noticeboard/models/notice_intro.dart';
import 'package:noticeboard/models/paginated_info.dart';
@@ -21,18 +26,28 @@ class ListNotices extends StatefulWidget {
}
class _ListNoticesState extends State {
- final ListNoticesBloc _listNoticesBloc = ListNoticesBloc();
+ final ListNoticesBloc _listNoticesBloc = ListNoticesBloc(); // search
final AuthRepository _authRepository = AuthRepository();
- TextEditingController? _controller; // search
+ final NoticeDetailBloc _noticeDetailBloc = NoticeDetailBloc();
+ final ConnectivityStatusBloc _connectivityStatusBloc =
+ ConnectivityStatusBloc();
+ TextEditingController? _controller;
@override
void initState() {
_controller = TextEditingController(); // search
_listNoticesBloc.context = context;
+ _connectivityStatusBloc.context = context;
+ _connectivityStatusBloc.currentWidget = CurrentWidget.listNotices;
_listNoticesBloc.listNoticeMetaData = widget.listNoticeMetaData;
_controller!.addListener(_handleQueryChanges);
_listNoticesBloc.dynamicFetch = widget.listNoticeMetaData!.dynamicFetch;
_listNoticesBloc.dynamicFetchNotices();
+ _noticeDetailBloc.eventStream.asBroadcastStream().listen((currentWidget) {
+ if (currentWidget == CurrentWidget.listNotices) {
+ _listNoticesBloc.dynamicFetchNotices();
+ }
+ });
super.initState();
}
diff --git a/noticeboard/lib/screens/notice_detail.dart b/noticeboard/lib/screens/notice_detail.dart
index e6c62c9..ac7c23d 100644
--- a/noticeboard/lib/screens/notice_detail.dart
+++ b/noticeboard/lib/screens/notice_detail.dart
@@ -1,4 +1,9 @@
+import 'dart:async';
import 'dart:convert';
+import 'dart:io';
+import 'package:noticeboard/bloc/connectivity_status_bloc.dart';
+import 'package:noticeboard/bloc/notice_detail_bloc.dart';
+import 'package:noticeboard/enum/current_widget_enum.dart';
import 'package:noticeboard/enum/notice_content_enum.dart';
import 'package:noticeboard/routes/routing_constants.dart';
import 'package:url_launcher/url_launcher_string.dart';
@@ -20,23 +25,40 @@ class NoticeDetail extends StatefulWidget {
class _NoticeDetailState extends State {
final NoticeIntro? noticeIntro;
+ // ignore: unused_element
_NoticeDetailState({this.noticeIntro});
-
+ final ConnectivityStatusBloc _connectivityStatusBloc =
+ ConnectivityStatusBloc();
NoticeContentBloc _noticeContentBloc = NoticeContentBloc();
+ WebViewController _webViewController = WebViewController();
+ NoticeDetailBloc _noticeDetailBloc = NoticeDetailBloc();
bool pdfAlreadyOpened = false;
+ late Timer _timer;
@override
void initState() {
_noticeContentBloc.context = context;
+ _connectivityStatusBloc.context = context;
+ _connectivityStatusBloc.currentWidget = CurrentWidget.noticeDetail;
_noticeContentBloc.noticeIntro = widget.noticeIntro;
_noticeContentBloc.starred = widget.noticeIntro!.starred;
_noticeContentBloc.eventSink.add(NoticeContentEvents.fetchContent);
+ _timer = addConnectivityStatusToSink();
+ _noticeDetailBloc.eventStream.listen((event) {
+ if (event == CurrentWidget.noticeDetail) {
+ _noticeContentBloc.eventSink.add(NoticeContentEvents.fetchContent);
+ _webViewController.reload();
+ }
+ });
super.initState();
}
@override
void dispose() {
_noticeContentBloc.disposeStreams();
+ if (_timer.isActive) {
+ _timer.cancel();
+ }
super.dispose();
}
@@ -72,7 +94,7 @@ class _NoticeDetailState extends State {
child: GestureDetector(
onPanUpdate: (details) {
// Can swipe anywhere and detects left swipe
- if (details.delta.dx < 0) {
+ if (details.delta.dx < 0 && Platform.isIOS) {
debugPrint("Left swipe occoured!");
if (previousRoute == launchingRoute) {
navigatorKey.currentState!
@@ -82,15 +104,18 @@ class _NoticeDetailState extends State {
}
}
},
- child: WillPopScope(
- onWillPop: () async {
+ child: PopScope(
+ canPop: false,
+ onPopInvoked: (didPop) async {
+ if (didPop) {
+ return;
+ }
if (previousRoute == launchingRoute) {
navigatorKey.currentState!
.pushReplacementNamed(bottomNavigationRoute);
} else {
navigatorKey.currentState!.pop();
}
- return false;
},
child: Container(
width: _width,
@@ -98,7 +123,7 @@ class _NoticeDetailState extends State {
child: Column(
children: [
buildNoticeIntro(_width),
- buildNoticeContent(_width)
+ buildNoticeContent(_width),
],
),
),
@@ -135,35 +160,33 @@ class _NoticeDetailState extends State {
mimeType: 'text/html',
encoding: Encoding.getByName('utf-8'),
);
- return Container(
- padding: EdgeInsets.all(10.0),
- child: WebView(
- initialUrl: uri.toString(),
- zoomEnabled: true,
- javascriptMode: JavascriptMode.unrestricted,
- allowsInlineMediaPlayback: true,
- navigationDelegate: (navigation) async {
- print(navigation.url);
- if (navigation.url.endsWith("pdf") && !pdfAlreadyOpened) {
- if (await canLaunchUrlString(navigation.url)) {
- String newUrl =
- "https://docs.google.com/gview?embedded=true&url=${navigation.url}";
- await launchUrlString(newUrl);
- }
+ _webViewController
+ ..enableZoom(true)
+ ..setJavaScriptMode(JavaScriptMode.unrestricted)
+ ..setNavigationDelegate(
+ NavigationDelegate(onNavigationRequest: (navigation) async {
+ if (navigation.url.endsWith("pdf") && !pdfAlreadyOpened) {
+ if (await canLaunchUrlString(navigation.url)) {
+ String newUrl =
+ "https://docs.google.com/gview?embedded=true&url=${navigation.url}";
+ await launchUrlString(newUrl);
+ }
+ return NavigationDecision.prevent;
+ } else {
+ if (await canLaunchUrlString(navigation.url)) {
+ await launchUrlString(
+ navigation.url,
+ mode: LaunchMode.externalApplication,
+ );
return NavigationDecision.prevent;
- } else {
- if (await canLaunchUrlString(navigation.url)) {
- await launchUrlString(
- navigation.url,
- mode: LaunchMode.externalApplication,
- );
- return NavigationDecision.prevent;
- }
}
- return NavigationDecision.navigate;
- },
- ),
- );
+ }
+ return NavigationDecision.navigate;
+ }))
+ ..loadRequest(uri);
+ return Container(
+ padding: EdgeInsets.all(10.0),
+ child: WebViewWidget(controller: _webViewController));
}
Container buildNoticeIntro(double _width) {
diff --git a/noticeboard/lib/screens/profile.dart b/noticeboard/lib/screens/profile.dart
index 5504f7a..6b124f5 100644
--- a/noticeboard/lib/screens/profile.dart
+++ b/noticeboard/lib/screens/profile.dart
@@ -1,4 +1,7 @@
+import 'dart:async';
+
import 'package:flutter/material.dart';
+import 'package:noticeboard/bloc/connectivity_status_bloc.dart';
import 'package:noticeboard/global/global_constants.dart';
import 'package:noticeboard/global/global_functions.dart';
import 'package:noticeboard/models/user_profile.dart';
@@ -16,16 +19,24 @@ class Profile extends StatefulWidget {
class _ProfileState extends State {
final ProfileBloc _profileBloc = ProfileBloc();
final AuthRepository _authRepository = AuthRepository();
-
+ final ConnectivityStatusBloc _connectivityStatusBloc =
+ ConnectivityStatusBloc();
+ late Timer _timer;
@override
void initState() {
_profileBloc.context = context;
+ _connectivityStatusBloc.context = context;
+ _timer = addConnectivityStatusToSink();
super.initState();
}
@override
void dispose() {
_profileBloc.disposeStreams();
+ if(_timer.isActive){
+ _timer.cancel();
+ }
+
super.dispose();
}
@@ -117,7 +128,8 @@ class _ProfileState extends State {
'Notification settings',
ProfileEvents.notificationSettingsEvent),
sizedBox(20.0),
- buildMenuItem(aboutUsIcon, "About us", ProfileEvents.aboutUsEvent),
+ buildMenuItem(
+ aboutUsIcon, "About us", ProfileEvents.aboutUsEvent),
sizedBox(20.0),
buildMenuItem(logoutIcon, 'Logout', ProfileEvents.logoutEvent)
],
diff --git a/noticeboard/pubspec.yaml b/noticeboard/pubspec.yaml
index 0e602e6..01c8181 100644
--- a/noticeboard/pubspec.yaml
+++ b/noticeboard/pubspec.yaml
@@ -38,7 +38,7 @@ dependencies:
flutter_form_builder: ^9.1.1
firebase_core: ^2.24.2
firebase_messaging: ^14.7.9
- webview_flutter: ^3.0.4
+ webview_flutter: ^4.7.0
uni_links: ^0.5.1
form_builder_validators: ^9.1.0