Merge pull request #3250 from dpalou/MOBILE-3833

Mobile 3833
main
Noel De Martin 2022-04-13 10:36:00 +02:00 committed by GitHub
commit 2c8850b669
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 69 additions and 13 deletions

View File

@ -657,6 +657,7 @@
"addon.mod_forum.posttoforum": "forum",
"addon.mod_forum.posttomygroups": "forum",
"addon.mod_forum.privatereply": "forum",
"addon.mod_forum.qandanotify": "forum",
"addon.mod_forum.re": "forum",
"addon.mod_forum.refreshposts": "local_moodlemobileapp",
"addon.mod_forum.removefromfavourites": "forum",

View File

@ -127,6 +127,11 @@
<ion-label>{{ 'addon.mod_assign.'+summary.warnofungroupedusers | translate }}</ion-label>
</ion-item>
</ion-card>
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<core-course-module-navigation [courseId]="courseId" [currentModuleId]="module.id">
</core-course-module-navigation>
</div>
</ng-container>
<!-- If it's a student, display his submission. -->

View File

@ -31,12 +31,20 @@
</ion-item>
</ion-card>
<!-- Q&A message. -->
<ion-card class="core-info-card" *ngIf="showQAMessage">
<ion-item>
<ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'addon.mod_forum.qandanotify' | translate }}</ion-label>
</ion-item>
</ion-card>
<ng-container *ngIf="forum">
<core-empty-box *ngIf="!discussions || discussions.empty" icon="far-comments"
<core-empty-box *ngIf="!discussions || !discussions.hasDiscussions" icon="far-comments"
[message]="'addon.mod_forum.forumnodiscussionsyet' | translate">
</core-empty-box>
<div *ngIf="discussions && !discussions.empty && sortingAvailable && selectedSortOrder" class="ion-text-wrap">
<div *ngIf="discussions?.hasDiscussions && sortingAvailable && selectedSortOrder" class="ion-text-wrap">
<core-combobox [modalOptions]="sortOrderSelectorModalOptions" listboxId="addon-mod-forum-sort-selector"
[label]="('core.sort' | translate)" (onChange)="setSortOrder($event)" [selection]="selectedSortOrder.label | translate"
interface="modal">

View File

@ -85,6 +85,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
sortOrders: AddonModForumSortOrder[] = [];
canPin = false;
hasOfflineRatings = false;
showQAMessage = false;
sortOrderSelectorModalOptions: ModalOptions = {
component: AddonModForumSortOrderSelectorComponent,
};
@ -345,8 +346,9 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
}
const forum = this.forum;
const showDueDateMessage = !CoreSites.getCurrentSite()?.isVersionGreaterEqualThan('3.11');
this.description = forum.intro || this.description;
this.availabilityMessage = AddonModForumHelper.getAvailabilityMessage(forum);
this.availabilityMessage = AddonModForumHelper.getAvailabilityMessage(forum, showDueDateMessage);
this.descriptionNote = Translate.instant('addon.mod_forum.numdiscussions', {
numdiscussions: forum.numdiscussions,
});
@ -403,6 +405,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
const cutoffDateReached = AddonModForumHelper.isCutoffDateReached(forum)
&& !accessInfo.cancanoverridecutoff;
this.canAddDiscussion = !!forum.cancreatediscussions && !cutoffDateReached;
this.showQAMessage = forum.type === 'qanda' && !accessInfo.canviewqandawithoutposting;
return;
}),
@ -702,4 +705,16 @@ class AddonModForumDiscussionsManager extends CoreListItemsManager<AddonModForum
}
}
/**
* Check whether there is any discussion in the items.
*
* @return Whether there is a discussion.
*/
get hasDiscussions(): boolean {
const source = this.getSource();
const items = source.getItems();
return items !== null && items.some(item => !source.isNewDiscussionForm(item));
}
}

View File

@ -49,6 +49,7 @@
"posttoforum": "Post to forum",
"posttomygroups": "Post a copy to all groups",
"privatereply": "Reply privately",
"qandanotify": "This is a question and answer forum. In order to see other responses to these questions, you must first post your answer",
"re": "Re:",
"refreshposts": "Refresh posts",
"removefromfavourites": "Unstar this discussion",

View File

@ -84,6 +84,14 @@
</ion-item>
</ion-card>
<!-- Q&A message. -->
<ion-card class="core-info-card" *ngIf="showQAMessage">
<ion-item>
<ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'addon.mod_forum.qandanotify' | translate }}</ion-label>
</ion-item>
</ion-card>
<div *ngIf="startingPost" class="ion-margin-bottom">
<addon-mod-forum-post [post]="startingPost" [discussion]="discussion" [courseId]="courseId" [highlight]="true"
[discussionId]="discussionId" [component]="component" [componentId]="cmId" [formData]="formData"

View File

@ -105,6 +105,7 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
cmId?: number;
canPin = false;
availabilityMessage: string | null = null;
showQAMessage = false;
leavingPage = false;
protected forumId?: number;
@ -493,6 +494,11 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
});
}
// Show Q&A message if user hasn't posted.
const currentUserId = CoreSites.getCurrentSiteUserId();
this.showQAMessage = forum.type === 'qanda' && !accessInfo.canviewqandawithoutposting &&
!posts.some(post => post.author.id === currentUserId);
return;
}),
);

View File

@ -278,23 +278,26 @@ export class AddonModForumHelperProvider {
* Returns the availability message of the given forum.
*
* @param forum Forum instance.
* @param getDueDateMessage Whether to get due date message. If false, only cutoff date message will be returned.
* @return Message or null if the forum has no cut-off or due date.
*/
getAvailabilityMessage(forum: AddonModForumData): string | null {
getAvailabilityMessage(forum: AddonModForumData, getDueDateMessage = true): string | null {
if (this.isCutoffDateReached(forum)) {
return Translate.instant('addon.mod_forum.cutoffdatereached');
}
if (this.isDueDateReached(forum)) {
const dueDate = CoreTimeUtils.userDate(forum.duedate * 1000);
if (getDueDateMessage) {
if (this.isDueDateReached(forum)) {
const dueDate = CoreTimeUtils.userDate(forum.duedate * 1000);
return Translate.instant('addon.mod_forum.thisforumisdue', { $a: dueDate });
}
return Translate.instant('addon.mod_forum.thisforumisdue', { $a: dueDate });
}
if ((forum.duedate ?? 0) > 0) {
const dueDate = CoreTimeUtils.userDate(forum.duedate! * 1000);
if (forum.duedate && forum.duedate > 0) {
const dueDate = CoreTimeUtils.userDate(forum.duedate * 1000);
return Translate.instant('addon.mod_forum.thisforumhasduedate', { $a: dueDate });
return Translate.instant('addon.mod_forum.thisforumhasduedate', { $a: dueDate });
}
}
return null;

View File

@ -65,7 +65,7 @@
</ng-container>
</ion-list>
<core-empty-box *ngIf="(!entries || entries.empty) && (!isSearch || hasSearched)" icon="fas-list"
<core-empty-box *ngIf="(!entries || !entries.hasEntries) && (!isSearch || hasSearched)" icon="fas-list"
[message]="'addon.mod_glossary.noentriesfound' | translate">
</core-empty-box>

View File

@ -472,4 +472,13 @@ class AddonModGlossaryEntriesManager extends CoreListItemsManager<AddonModGlossa
}
}
/**
* Check whether there is any entry in the items.
*
* @return Whether there is an entry.
*/
get hasEntries(): boolean {
return this.getSource().onlineEntries.length > 0 || this.getSource().offlineEntries.length > 0;
}
}

View File

@ -34,7 +34,7 @@
</div>
<!-- Availability info space. -->
<div class="core-module-availabilityinfo core-module-info-box-section" *ngIf="showAvailabilityInfo">
<div class="core-module-availabilityinfo core-module-info-box-section" *ngIf="showAvailabilityInfo && module.availabilityinfo">
<ion-icon name="fas-lock" [attr.aria-label]="'core.restricted' | translate"></ion-icon>
<core-format-text [text]="module.availabilityinfo" contextLevel="module" [contextInstanceId]="module.id" [courseId]="module.course">
</core-format-text>