Skip to content

Commit

Permalink
Merge pull request #691 from rokwire/release/v2.6.18+718
Browse files Browse the repository at this point in the history
Release/v2.6.18+718
  • Loading branch information
sandeep-ps authored Aug 12, 2021
2 parents 5edaa39 + 5433370 commit 5169873
Show file tree
Hide file tree
Showing 39 changed files with 1,335 additions and 1,271 deletions.
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

## [2.6.18] - 2021-08-12
### Changed
- Updated Dining Dollars icon [#682](https://github.com/rokwire/illinois-app/issues/682).
### Fixed
- Display group website link for members and admins as well [#681](https://github.com/rokwire/illinois-app/issues/681).
- Fixed action for StudentGuide library-card feature [#684](https://github.com/rokwire/illinois-app/issues/684).
- Check in FlexUI whether relevant StudentGuide feature are available before displaying it [#684](https://github.com/rokwire/illinois-app/issues/684).
- Parsing group membership questions to json [#417](https://github.com/rokwire/illinois-app/issues/417).
- Fixed onboarding screens that used ScaleableScrollView [#679](https://github.com/rokwire/illinois-app/issues/679).

## [2.6.17] - 2021-08-11
### Fixed
- Additional fix which prevents UI blocking if the user cancels the login process[#357](https://github.com/rokwire/illinois-app/issues/357).
- Display start time for events from Athletics category [#636](https://github.com/rokwire/illinois-app/issues/636).
- Display options menu in GroupAllEventsPanel for group admins [#637](https://github.com/rokwire/illinois-app/issues/637).
- Remove check if user is employee when creating group and change permissions error message [#663](https://github.com/rokwire/illinois-app/issues/663).
### Added
- Add three new buttons to mental wellness [#674](https://github.com/rokwire/illinois-app/issues/674).
### Changed
- Updated Dining Dollars icon [#669](https://github.com/rokwire/illinois-app/issues/669).

## [2.6.16] - 2021-08-04
### Fixed
- Allow only users with granted permissions to create a group [#663](https://github.com/rokwire/illinois-app/issues/663).

## [2.6.15] - 2021-08-03
### Fixed
- Do not allow editing events for non-group events [#658](https://github.com/rokwire/illinois-app/issues/658).

## [2.6.14] - 2021-07-30
### Fixed
- Do not evaluate number of group replies recursively [#651](https://github.com/rokwire/illinois-app/issues/651).
Expand Down
20 changes: 20 additions & 0 deletions assets/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,26 @@
},
"description": {
"main_text": "panel.wellness.mental.description.main_text",
"ribbon_buttons": [
{
"title": "panel.wellness.mental.description.buttons.appointment",
"url": "https://wellness.web.illinois.edu/help/i-want-to-make-an-appointment/",
"icon": "link-out.png",
"hint": ""
},
{
"title": "panel.wellness.mental.description.buttons.help_friend",
"url": "https://wellness.web.illinois.edu/help/i-want-to-help-a-friend-student-or-coworker/",
"icon": "link-out.png",
"hint": ""
},
{
"title": "panel.wellness.mental.description.buttons.where_to_start",
"url": "https://wellness.web.illinois.edu/help/im-not-sure-where-to-start",
"icon": "link-out.png",
"hint": ""
}
],
"bullet": "panel.wellness.common.description.bullet",
"secondary_text": "panel.wellness.mental.description.secondary_text"
},
Expand Down
4 changes: 4 additions & 0 deletions assets/strings.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,9 @@
"panel.wellness.mental.header.title": "Mental Wellness",
"panel.wellness.mental.description.main_text": "Intellectual wellness involves having an open mind when you encounter new ideas and involves lifelong learning. It encourages active participation in scholastic, cultural and community activities.",
"panel.wellness.mental.description.secondary_text": "Take classes offered in your community, participate in something contrary to your strengths and comfort level.",
"panel.wellness.mental.description.buttons.appointment": "I want to make an appointment",
"panel.wellness.mental.description.buttons.help_friend": "I want to help a friend, student or co-worker",
"panel.wellness.mental.description.buttons.where_to_start": "I’m not sure where to start",
"panel.wellness.mental.interactive_activities.activity.mixup": "Memory Mixup",
"panel.wellness.mental.resources.counseling": "Counseling",
"panel.wellness.mental.resources.outreach": "Outreach and Prevention",
Expand Down Expand Up @@ -1448,6 +1451,7 @@
"panel.groups_create.button.tags.title": "Tags",
"panel.groups_create.button.tags.hint": "",
"panel.groups_create.failed.msg": "Failed to create group: %s.",
"panel.groups_create.unknown.error.message": "Unknown error occurred",
"panel.groups_update.failed.msg": "Failed to update group: %s.",
"panel.groups_create.membership.section.title": "Membership",
"panel.groups_create.questions.existing.label": "Question(s)",
Expand Down
4 changes: 4 additions & 0 deletions assets/strings.es.json
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,9 @@
"panel.wellness.mental.header.title": "Bienestar mental",
"panel.wellness.mental.description.main_text": "El bienestar intelectual implica tener una mente abierta cuando te encuentras con nuevas ideas e implica un aprendizaje permanente. Fomenta la participación activa en actividades escolares, culturales y comunitarias.",
"panel.wellness.mental.description.secondary_text": "Tome clases ofrecidas en su comunidad, participe en algo contrario a sus fortalezas y nivel de comodidad.",
"panel.wellness.mental.description.buttons.appointment": "Quiero hacer una cita",
"panel.wellness.mental.description.buttons.help_friend": "Quiero ayudar a un amigo, estudiante o compañero de trabajo",
"panel.wellness.mental.description.buttons.where_to_start": "No estoy seguro de por dónde empezar",
"panel.wellness.mental.interactive_activities.activity.mixup": "Mezcla de memoria",
"panel.wellness.mental.resources.counseling": "Asesoramiento",
"panel.wellness.mental.resources.outreach": "Alcance y Prevención",
Expand Down Expand Up @@ -1449,6 +1452,7 @@
"panel.groups_create.button.tags.title": "Tags",
"panel.groups_create.button.tags.hint": "",
"panel.groups_create.failed.msg": "Failed to create group: %s.",
"panel.groups_create.unknown.error.message": "Unknown error occurred",
"panel.groups_update.failed.msg": "Failed to update group: %s.",
"panel.groups_create.membership.section.title": "Membership",
"panel.groups_create.questions.existing.label": "Question(s)",
Expand Down
4 changes: 4 additions & 0 deletions assets/strings.zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,9 @@
"panel.wellness.mental.header.title": "心理健康",
"panel.wellness.mental.description.main_text": "智力健康包括当你遇到新的想法时有一个开放的心态,包括终身学习。它鼓励积极参与学校、文化和社区活动",
"panel.wellness.mental.description.secondary_text": "參加您所在社區提供的課程,參加一些與您的長處和舒適水平相反的活動。",
"panel.wellness.mental.description.buttons.appointment": "我想預約",
"panel.wellness.mental.description.buttons.help_friend": "我想幫助朋友, 學生或同事",
"panel.wellness.mental.description.buttons.where_to_start": "我不知道從哪裡開始",
"panel.wellness.mental.interactive_activities.activity.mixup": "记忆混淆",
"panel.wellness.mental.resources.counseling": "心理諮詢",
"panel.wellness.mental.resources.outreach": "外展與預防",
Expand Down Expand Up @@ -1447,6 +1450,7 @@
"panel.groups_create.button.tags.title": "Tags",
"panel.groups_create.button.tags.hint": "",
"panel.groups_create.failed.msg": "Failed to create group: %s.",
"panel.groups_create.unknown.error.message": "Unknown error occurred",
"panel.groups_update.failed.msg": "Failed to update group: %s.",
"panel.groups_create.membership.section.title": "Membership",
"panel.groups_create.questions.existing.label": "Question(s)",
Expand Down
Binary file modified images/2.0x/icon-payment-type-dining-dollars.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/3.0x/icon-payment-type-dining-dollars.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/icon-payment-type-dining-dollars.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 6 additions & 7 deletions lib/model/Event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -585,23 +585,22 @@ class Event with Explore implements Favorite {
///
/// Specific for Events with 'Athletics' category
///
/// Requirement 1:
/// Requirement 1 (Deprecated! since 08/11/2021):
/// 'When in explore/events and the category is athletics, do not show the time anymore, just the date. Also do not process it for timezone (now we go to athletics detail panel we will rely on how detail already deals with any issues)'
///
/// Requirement 2: 'If an event is longer than 1 day, then please show the Date as (for example) Sep 26 - Sep 29.'
///
/// Requirement 3 (Since 08/11/2021): Display start time for Athletics events
///
String get displayDateTime {
final String dateFormat = 'MMM dd';
final bool isAthleticsCategory = (category == 'Athletics');
int eventDays = (endDateGmt?.difference(startDateGmt)?.inDays ?? 0).abs();
bool eventIsMoreThanOneDay = (eventDays >= 1);
if (eventIsMoreThanOneDay) {
String startDateFormatted = AppDateTime().formatDateTime(startDateGmt, format: dateFormat, ignoreTimeZone: isAthleticsCategory);
String endDateFormatted = AppDateTime().formatDateTime(endDateGmt, format: dateFormat, ignoreTimeZone: isAthleticsCategory);
String startDateFormatted = AppDateTime().formatDateTime(startDateGmt, format: dateFormat);
String endDateFormatted = AppDateTime().formatDateTime(endDateGmt, format: dateFormat);
return '$startDateFormatted - $endDateFormatted';
} else {
if (isAthleticsCategory) {
return AppDateTime().formatDateTime(startDateGmt, format: dateFormat, ignoreTimeZone: true);
}
return AppDateTime().getDisplayDateTime(startDateGmt, allDay: allDay);
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/model/Groups.dart
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ class GroupMembershipQuestion {
if (values != null) {
strings = <String>[];
for (GroupMembershipQuestion value in values) {
strings.add(value.toString());
strings.add(value.question);
}
}
return strings;
Expand Down
122 changes: 69 additions & 53 deletions lib/service/Auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ class Auth with Service implements NotificationsListener {

static final Auth _auth = Auth._internal();

final List<Completer<bool>> _loginCompleters = [];
Timer _loginTimer;
List<Completer<bool>> _shibbolethAuthenticationCompleters;
bool _processingShibbolethAuthentication;
Timer _shibbolethAuthenticationTimer;

AuthToken _authToken;
AuthToken get authToken{ return _authToken; }
Expand Down Expand Up @@ -164,11 +165,18 @@ class Auth with Service implements NotificationsListener {
return authInfo?.userGroupMembership?.contains('urn:mace:uiuc.edu:urbana:authman:app-rokwire-service-policy-rokwire debug') ?? false;
}

bool get isGroupsAccess {
return authInfo?.userGroupMembership?.contains('urn:mace:uiuc.edu:urbana:authman:app-rokwire-service-policy-rokwire groups access') ?? false;
}

bool isMemberOf(String groupName) {
return authInfo?.userGroupMembership?.contains(groupName) ?? false;
}

void logout(){
_cancelShibbolethAuthenticationTimer();
_completeShibbolethAuthentication(false);

_clear(true);
}

Expand All @@ -194,33 +202,48 @@ class Auth with Service implements NotificationsListener {
////////////////////////
// Shibboleth Oauth

Future<bool> authenticateWithShibboleth() async{

if (_loginCompleters.isEmpty && (Config().shibbolethOauthHostUrl != null) && (Config().shibbolethOauthPathUrl != null) && (Config().shibbolethClientId != null)) {
Uri uri = Uri.https(
Config().shibbolethOauthHostUrl,
Config().shibbolethOauthPathUrl,
{
'scope': "openid profile email offline_access",
'response_type': 'code',
'redirect_uri': REDIRECT_URI,
'client_id': Config().shibbolethClientId,
'claims': json.jsonEncode({
'userinfo': {
'uiucedu_uin': {'essential': true},
},
}),
},
);
var uriStr = uri.toString();
_launchUrl(uriStr);
Future<bool> authenticateWithShibboleth() async {
if ((Config().shibbolethOauthHostUrl != null) && (Config().shibbolethOauthPathUrl != null) && (Config().shibbolethClientId != null)) {
if (_shibbolethAuthenticationCompleters == null) {
_shibbolethAuthenticationCompleters = <Completer<bool>>[];

Uri uri = Uri.https(
Config().shibbolethOauthHostUrl,
Config().shibbolethOauthPathUrl,
{
'scope': "openid profile email offline_access",
'response_type': 'code',
'redirect_uri': REDIRECT_URI,
'client_id': Config().shibbolethClientId,
'claims': json.jsonEncode({
'userinfo': {
'uiucedu_uin': {'essential': true},
},
}),
},
);
var uriStr = uri.toString();
await _launchUrl(uriStr);
}

Completer<bool> completer = Completer<bool>();
_shibbolethAuthenticationCompleters.add(completer);
return completer.future;
}

return _createLoginCompleter();
return false;
}

Future<bool> _handleShibbolethAuthentication(code) async {
_cancelShibbolethAuthenticationTimer();
_processingShibbolethAuthentication = true;
bool result = await _processShibbolethAuthentication(code);
_processingShibbolethAuthentication = null;
_completeShibbolethAuthentication(result);
return result;
}

Future<bool> _processShibbolethAuthentication(code) async {
_notifyAuthStarted();

NativeCommunicator().dismissSafariVC();
Expand All @@ -229,23 +252,20 @@ class Auth with Service implements NotificationsListener {
AuthToken newAuthToken = await _loadShibbolethAuthTokenWithCode(code);
if(newAuthToken == null){
_notifyAuthLoginFailed(analyticsAction: Analytics.LogAuthLoginNetIdActionName);
_completeLoginWithResult(false);
return false;
}

// 2. Request AuthInfo
AuthInfo newAuthInfo = await _loadAuthInfo(optAuthToken: newAuthToken);
if(newAuthInfo == null){
_notifyAuthLoginFailed(analyticsAction: Analytics.LogAuthLoginNetIdActionName);
_completeLoginWithResult(false);
return false;
}

// 3. Request User Pii Pid
String newUserPiiPid = await _loadPidWithShibbolethAuth(email: newAuthInfo?.email, optAuthToken: newAuthToken);
if(newUserPiiPid == null){
_notifyAuthLoginFailed(analyticsAction: Analytics.LogAuthLoginNetIdActionName);
_completeLoginWithResult(false);
return false;
}

Expand All @@ -254,7 +274,6 @@ class Auth with Service implements NotificationsListener {
UserPiiData newUserPiiData = _userPiiDataFromJsonString(newUserPiiDataString);
if(newUserPiiData == null || AppCollection.isCollectionEmpty(newUserPiiData?.uuidList)){
_notifyAuthLoginFailed(analyticsAction: Analytics.LogAuthLoginNetIdActionName);
_completeLoginWithResult(false);
return false;
}

Expand All @@ -265,7 +284,6 @@ class Auth with Service implements NotificationsListener {
} on UserNotFoundException catch (_) {}
if(newUserData == null){
_notifyAuthLoginFailed(analyticsAction: Analytics.LogAuthLoginNetIdActionName);
_completeLoginWithResult(false);
return false;
}

Expand Down Expand Up @@ -310,7 +328,6 @@ class Auth with Service implements NotificationsListener {

_notifyAuthLoginSucceeded(analyticsAction: Analytics.LogAuthLoginNetIdActionName);

_completeLoginWithResult(true);
return true;
}

Expand Down Expand Up @@ -363,7 +380,7 @@ class Auth with Service implements NotificationsListener {
return null;
}

void _launchUrl(urlStr) async {
Future<void> _launchUrl(urlStr) async {
try {
if (await url_launcher.canLaunch(urlStr)) {
await url_launcher.launch(urlStr);
Expand Down Expand Up @@ -871,6 +888,7 @@ class Auth with Service implements NotificationsListener {
if (param == AppLifecycleState.resumed) {
_reloadAuthCardIfNeeded();
_reloadUserPiiDataIfNeeded();
_createShibbolethAuthenticationTimerIfNeeded();
}
}
else if (name == User.notifyPrivacyLevelChanged) {
Expand Down Expand Up @@ -905,38 +923,36 @@ class Auth with Service implements NotificationsListener {
}
}

void _createLoginTimer(){
if(_loginTimer != null){
_loginTimer.cancel();
void _createShibbolethAuthenticationTimerIfNeeded() {
if ((_shibbolethAuthenticationCompleters != null) && (_processingShibbolethAuthentication != true)) {
if (_shibbolethAuthenticationTimer != null) {
_shibbolethAuthenticationTimer.cancel();
}
_shibbolethAuthenticationTimer = Timer(Duration(milliseconds: 100), () {
_completeShibbolethAuthentication(null);
_shibbolethAuthenticationTimer = null;
});
}
_loginTimer = Timer(Duration(minutes: 10), (){
_completeLoginWithResult(false);
_loginTimer = null;
});
}

void _cancelLoginTimer(){
if(_loginTimer != null){
_loginTimer.cancel();
void _cancelShibbolethAuthenticationTimer() {
if(_shibbolethAuthenticationTimer != null){
_shibbolethAuthenticationTimer.cancel();
_shibbolethAuthenticationTimer = null;
}
_loginTimer = null;
}

Future<bool> _createLoginCompleter(){
Completer<bool> completer = Completer<bool>();
_loginCompleters.add(completer);
_createLoginTimer();
return completer.future;
}
void _completeShibbolethAuthentication(bool success){
if (_shibbolethAuthenticationCompleters != null) {
List<Completer<bool>> loginCompleters = _shibbolethAuthenticationCompleters;
_shibbolethAuthenticationCompleters = null;

void _completeLoginWithResult(bool success){
for(Completer<void> completer in _loginCompleters){
completer.complete(success);
for(Completer<void> completer in loginCompleters){
completer.complete(success);
}
}
_cancelLoginTimer();
_loginCompleters.clear();
}

}

enum VerificationMethod { call, sms }
enum VerificationMethod { call, sms }
Loading

0 comments on commit 5169873

Please sign in to comment.