Merge pull request #1890 from albertgasset/MOBILE-2989

Mobile 2989
main
Juan Leyva 2019-05-07 19:31:46 +02:00 committed by GitHub
commit a440f1cd78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 166 additions and 4 deletions

View File

@ -478,6 +478,7 @@
"addon.mod_forum.addanewdiscussion": "forum", "addon.mod_forum.addanewdiscussion": "forum",
"addon.mod_forum.addanewquestion": "forum", "addon.mod_forum.addanewquestion": "forum",
"addon.mod_forum.addanewtopic": "forum", "addon.mod_forum.addanewtopic": "forum",
"addon.mod_forum.addtofavourites": "forum",
"addon.mod_forum.advanced": "forum", "addon.mod_forum.advanced": "forum",
"addon.mod_forum.cannotadddiscussion": "forum", "addon.mod_forum.cannotadddiscussion": "forum",
"addon.mod_forum.cannotadddiscussionall": "forum", "addon.mod_forum.cannotadddiscussionall": "forum",
@ -492,9 +493,11 @@
"addon.mod_forum.erroremptysubject": "forum", "addon.mod_forum.erroremptysubject": "forum",
"addon.mod_forum.errorgetforum": "local_moodlemobileapp", "addon.mod_forum.errorgetforum": "local_moodlemobileapp",
"addon.mod_forum.errorgetgroups": "local_moodlemobileapp", "addon.mod_forum.errorgetgroups": "local_moodlemobileapp",
"addon.mod_forum.favouriteupdated": "forum",
"addon.mod_forum.forumnodiscussionsyet": "local_moodlemobileapp", "addon.mod_forum.forumnodiscussionsyet": "local_moodlemobileapp",
"addon.mod_forum.group": "local_moodlemobileapp", "addon.mod_forum.group": "local_moodlemobileapp",
"addon.mod_forum.locked": "forum", "addon.mod_forum.locked": "forum",
"addon.mod_forum.lockupdated": "forum",
"addon.mod_forum.message": "forum", "addon.mod_forum.message": "forum",
"addon.mod_forum.modeflatnewestfirst": "forum", "addon.mod_forum.modeflatnewestfirst": "forum",
"addon.mod_forum.modeflatoldestfirst": "forum", "addon.mod_forum.modeflatoldestfirst": "forum",
@ -503,15 +506,19 @@
"addon.mod_forum.notlocked": "forum", "addon.mod_forum.notlocked": "forum",
"addon.mod_forum.numdiscussions": "local_moodlemobileapp", "addon.mod_forum.numdiscussions": "local_moodlemobileapp",
"addon.mod_forum.numreplies": "local_moodlemobileapp", "addon.mod_forum.numreplies": "local_moodlemobileapp",
"addon.mod_forum.pindiscussion": "forum",
"addon.mod_forum.pinupdated": "forum",
"addon.mod_forum.postisprivatereply": "forum", "addon.mod_forum.postisprivatereply": "forum",
"addon.mod_forum.posttoforum": "forum", "addon.mod_forum.posttoforum": "forum",
"addon.mod_forum.privatereply": "forum", "addon.mod_forum.privatereply": "forum",
"addon.mod_forum.re": "forum", "addon.mod_forum.re": "forum",
"addon.mod_forum.refreshdiscussions": "local_moodlemobileapp", "addon.mod_forum.refreshdiscussions": "local_moodlemobileapp",
"addon.mod_forum.refreshposts": "local_moodlemobileapp", "addon.mod_forum.refreshposts": "local_moodlemobileapp",
"addon.mod_forum.removefromfavourites": "forum",
"addon.mod_forum.reply": "forum", "addon.mod_forum.reply": "forum",
"addon.mod_forum.replyplaceholder": "forum", "addon.mod_forum.replyplaceholder": "forum",
"addon.mod_forum.subject": "forum", "addon.mod_forum.subject": "forum",
"addon.mod_forum.unpindiscussion": "forum",
"addon.mod_forum.unread": "forum", "addon.mod_forum.unread": "forum",
"addon.mod_forum.unreadpostsnumber": "forum", "addon.mod_forum.unreadpostsnumber": "forum",
"addon.mod_glossary.addentry": "glossary", "addon.mod_glossary.addentry": "glossary",

View File

@ -45,7 +45,11 @@
<ion-card *ngFor="let discussion of discussions" (click)="openDiscussion(discussion)" [class.addon-forum-discussion-selected]="discussion.discussion == selectedDiscussion"> <ion-card *ngFor="let discussion of discussions" (click)="openDiscussion(discussion)" [class.addon-forum-discussion-selected]="discussion.discussion == selectedDiscussion">
<ion-item text-wrap> <ion-item text-wrap>
<ion-avatar core-user-avatar [user]="discussion" item-start [courseId]="courseId"></ion-avatar> <ion-avatar core-user-avatar [user]="discussion" item-start [courseId]="courseId"></ion-avatar>
<h2><core-icon name="fa-map-pin" *ngIf="discussion.pinned"></core-icon> <core-format-text [text]="discussion.subject"></core-format-text></h2> <h2>
<core-icon name="fa-map-pin" *ngIf="discussion.pinned"></core-icon>
<core-icon name="fa-star" class="addon-forum-star" *ngIf="!discussion.pinned && discussion.starred"></core-icon>
<core-format-text [text]="discussion.subject"></core-format-text>
</h2>
<p> <p>
<ion-note float-end padding-left text-end> <ion-note float-end padding-left text-end>
{{discussion.created | coreDateDayOrTime}} {{discussion.created | coreDateDayOrTime}}

View File

@ -2,4 +2,7 @@ ion-app.app-root addon-mod-forum-index {
.addon-forum-discussion-selected { .addon-forum-discussion-selected {
border-top: 5px solid $core-splitview-selected; border-top: 5px solid $core-splitview-selected;
} }
.addon-forum-star {
color: $core-star-color;
}
} }

View File

@ -1,7 +1,11 @@
<ion-card-header text-wrap no-padding id="addon-mod_forum-post-{{post.id}}"> <ion-card-header text-wrap no-padding id="addon-mod_forum-post-{{post.id}}">
<ion-item text-wrap> <ion-item text-wrap>
<ion-avatar core-user-avatar [user]="post" item-start (click)="openUserProfile(post.userid)"></ion-avatar> <ion-avatar core-user-avatar [user]="post" item-start (click)="openUserProfile(post.userid)"></ion-avatar>
<h2><span [class.core-bold]="post.parent == 0"><core-format-text [text]="post.subject"></core-format-text></span></h2> <h2>
<core-icon name="fa-map-pin" *ngIf="post.parent == 0 && post.pinned"></core-icon>
<core-icon name="fa-star" class="addon-forum-star" *ngIf="post.parent == 0 && !post.pinned && post.starred"></core-icon>
<span [class.core-bold]="post.parent == 0"><core-format-text [text]="post.subject"></core-format-text></span>
</h2>
<p> <p>
<ion-note float-end padding-left *ngIf="!post.modified"><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</ion-note> <ion-note float-end padding-left *ngIf="!post.modified"><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</ion-note>
<ion-note float-end padding-left text-end *ngIf="post.modified"> <ion-note float-end padding-left text-end *ngIf="post.modified">

View File

@ -0,0 +1,5 @@
ion-app.app-root addon-mod-forum-post {
.addon-forum-star {
color: $core-star-color;
}
}

View File

@ -2,6 +2,7 @@
"addanewdiscussion": "Add a new discussion topic", "addanewdiscussion": "Add a new discussion topic",
"addanewquestion": "Add a new question", "addanewquestion": "Add a new question",
"addanewtopic": "Add a new topic", "addanewtopic": "Add a new topic",
"addtofavourites": "Star this discussion",
"advanced": "Advanced", "advanced": "Advanced",
"cannotadddiscussion": "Adding discussions to this forum requires group membership.", "cannotadddiscussion": "Adding discussions to this forum requires group membership.",
"cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.", "cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.",
@ -16,9 +17,11 @@
"erroremptysubject": "Post subject cannot be empty.", "erroremptysubject": "Post subject cannot be empty.",
"errorgetforum": "Error getting forum data.", "errorgetforum": "Error getting forum data.",
"errorgetgroups": "Error getting group settings.", "errorgetgroups": "Error getting group settings.",
"favouriteupdated": "Your star option has been updated.",
"forumnodiscussionsyet": "There are no discussions yet in this forum.", "forumnodiscussionsyet": "There are no discussions yet in this forum.",
"group": "Group", "group": "Group",
"locked": "Locked", "locked": "Locked",
"lockupdated": "The lock option has been updated.",
"message": "Message", "message": "Message",
"modeflatnewestfirst": "Display replies flat, with newest first", "modeflatnewestfirst": "Display replies flat, with newest first",
"modeflatoldestfirst": "Display replies flat, with oldest first", "modeflatoldestfirst": "Display replies flat, with oldest first",
@ -27,15 +30,19 @@
"notlocked": "Lock", "notlocked": "Lock",
"numdiscussions": "{{numdiscussions}} discussions", "numdiscussions": "{{numdiscussions}} discussions",
"numreplies": "{{numreplies}} replies", "numreplies": "{{numreplies}} replies",
"pindiscussion": "Pin this discussion",
"pinupdated": "The pin option has been updated.",
"postisprivatereply": "This post was made privately and is not visible to all users.", "postisprivatereply": "This post was made privately and is not visible to all users.",
"posttoforum": "Post to forum", "posttoforum": "Post to forum",
"privatereply": "Reply privately", "privatereply": "Reply privately",
"re": "Re:", "re": "Re:",
"refreshdiscussions": "Refresh discussions", "refreshdiscussions": "Refresh discussions",
"refreshposts": "Refresh posts", "refreshposts": "Refresh posts",
"removefromfavourites": "Unstar this discussion",
"reply": "Reply", "reply": "Reply",
"replyplaceholder": "Write your reply...", "replyplaceholder": "Write your reply...",
"subject": "Subject", "subject": "Subject",
"unpindiscussion": "Unpin this discussion",
"unread": "Unread", "unread": "Unread",
"unreadpostsnumber": "{{$a}} unread posts" "unreadpostsnumber": "{{$a}} unread posts"
} }

View File

@ -15,6 +15,10 @@
<core-context-menu-item [hidden]="sort == 'nested'" [priority]="400" [content]="'addon.mod_forum.modenested' | translate" (action)="changeSort('nested')" iconAction="swap"></core-context-menu-item> <core-context-menu-item [hidden]="sort == 'nested'" [priority]="400" [content]="'addon.mod_forum.modenested' | translate" (action)="changeSort('nested')" iconAction="swap"></core-context-menu-item>
<core-context-menu-item [hidden]="!discussion || !discussion.canlock || discussion.locked" [priority]="300" [content]="'addon.mod_forum.notlocked' | translate" (action)="setLockState(true)" iconAction="fa-unlock"></core-context-menu-item> <core-context-menu-item [hidden]="!discussion || !discussion.canlock || discussion.locked" [priority]="300" [content]="'addon.mod_forum.notlocked' | translate" (action)="setLockState(true)" iconAction="fa-unlock"></core-context-menu-item>
<core-context-menu-item [hidden]="!discussion || !discussion.canlock || !discussion.locked" [priority]="300" [content]="'addon.mod_forum.locked' | translate" (action)="setLockState(false)" iconAction="fa-lock"></core-context-menu-item> <core-context-menu-item [hidden]="!discussion || !discussion.canlock || !discussion.locked" [priority]="300" [content]="'addon.mod_forum.locked' | translate" (action)="setLockState(false)" iconAction="fa-lock"></core-context-menu-item>
<core-context-menu-item [hidden]="!discussion || !canPin || discussion.pinned" [priority]="250" [content]="'addon.mod_forum.pindiscussion' | translate" (action)="setPinState(true)" iconAction="fa-map-pin"></core-context-menu-item>
<core-context-menu-item [hidden]="!discussion || !canPin || !discussion.pinned" [priority]="250" [content]="'addon.mod_forum.unpindiscussion' | translate" (action)="setPinState(false)" iconAction="fa-map-pin" [iconSlash]="true"></core-context-menu-item>
<core-context-menu-item [hidden]="!discussion || !discussion.canfavourite || discussion.starred" [priority]="200" [content]="'addon.mod_forum.addtofavourites' | translate" (action)="toggleFavouriteState(true)" iconAction="fa-star"></core-context-menu-item>
<core-context-menu-item [hidden]="!discussion || !discussion.canfavourite || !discussion.starred" [priority]="200" [content]="'addon.mod_forum.removefromfavourites' | translate" (action)="toggleFavouriteState(false)" iconAction="fa-star" [iconSlash]="true"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>
<ion-content> <ion-content>

View File

@ -76,6 +76,7 @@ export class AddonModForumDiscussionPage implements OnDestroy {
discussionStr = ''; discussionStr = '';
component = AddonModForumProvider.COMPONENT; component = AddonModForumProvider.COMPONENT;
cmId: number; cmId: number;
canPin = false;
protected forumId: number; protected forumId: number;
protected postId: number; protected postId: number;
@ -349,6 +350,17 @@ export class AddonModForumDiscussionPage implements OnDestroy {
this.posts = posts; this.posts = posts;
this.ratingInfo = ratingInfo; this.ratingInfo = ratingInfo;
}); });
}).then(() => {
if (this.forumProvider.isSetPinStateAvailableForSite()) {
// Use the canAddDiscussion WS to check if the user can pin discussions.
return this.forumProvider.canAddDiscussionToAll(this.forumId).then((response) => {
this.canPin = !!response.canpindiscussions;
}).catch(() => {
this.canPin = false;
});
} else {
this.canPin = false;
}
}).then(() => { }).then(() => {
return this.ratingOffline.hasRatings('mod_forum', 'post', 'module', this.cmId, this.discussionId).then((hasRatings) => { return this.ratingOffline.hasRatings('mod_forum', 'post', 'module', this.cmId, this.discussionId).then((hasRatings) => {
this.hasOfflineRatings = hasRatings; this.hasOfflineRatings = hasRatings;
@ -491,6 +503,62 @@ export class AddonModForumDiscussionPage implements OnDestroy {
locked: this.discussion.locked locked: this.discussion.locked
}; };
this.eventsProvider.trigger(AddonModForumProvider.CHANGE_DISCUSSION_EVENT, data, this.sitesProvider.getCurrentSiteId()); this.eventsProvider.trigger(AddonModForumProvider.CHANGE_DISCUSSION_EVENT, data, this.sitesProvider.getCurrentSiteId());
this.domUtils.showToast('addon.mod_forum.lockupdated', true);
}).catch((error) => {
this.domUtils.showErrorModal(error);
}).finally(() => {
modal.dismiss();
});
}
/**
* Pin or unpin the discussion.
*
* @param {boolean} pinned True to pin the discussion, false to unpin it.
*/
setPinState(pinned: boolean): void {
const modal = this.domUtils.showModalLoading('core.sending', true);
this.forumProvider.setPinState(this.discussionId, pinned).then(() => {
this.discussion.pinned = pinned;
const data = {
forumId: this.forumId,
discussionId: this.discussionId,
cmId: this.cmId,
pinned: this.discussion.pinned
};
this.eventsProvider.trigger(AddonModForumProvider.CHANGE_DISCUSSION_EVENT, data, this.sitesProvider.getCurrentSiteId());
this.domUtils.showToast('addon.mod_forum.pinupdated', true);
}).catch((error) => {
this.domUtils.showErrorModal(error);
}).finally(() => {
modal.dismiss();
});
}
/**
* Star or unstar the discussion.
*
* @param {boolean} starred True to star the discussion, false to unstar it.
*/
toggleFavouriteState(starred: boolean): void {
const modal = this.domUtils.showModalLoading('core.sending', true);
this.forumProvider.toggleFavouriteState(this.discussionId, starred).then(() => {
this.discussion.starred = starred;
const data = {
forumId: this.forumId,
discussionId: this.discussionId,
cmId: this.cmId,
starred: this.discussion.starred
};
this.eventsProvider.trigger(AddonModForumProvider.CHANGE_DISCUSSION_EVENT, data, this.sitesProvider.getCurrentSiteId());
this.domUtils.showToast('addon.mod_forum.favouriteupdated', true);
}).catch((error) => { }).catch((error) => {
this.domUtils.showErrorModal(error); this.domUtils.showErrorModal(error);
}).finally(() => { }).finally(() => {

View File

@ -14,6 +14,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreSite } from '@classes/site';
import { CoreAppProvider } from '@providers/app'; import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreGroupsProvider } from '@providers/groups'; import { CoreGroupsProvider } from '@providers/groups';
@ -784,6 +785,59 @@ export class AddonModForumProvider {
}); });
} }
/**
* Returns whether the set pin state WS is available.
*
* @param {CoreSite} [site] Site. If not defined, current site.
* @return {boolean} Whether it's available.
* @since 3.7
*/
isSetPinStateAvailableForSite(site?: CoreSite): boolean {
site = site || this.sitesProvider.getCurrentSite();
return this.sitesProvider.wsAvailableInCurrentSite('mod_forum_set_pin_state');
}
/**
* Pin or unpin a discussion.
*
* @param {number} discussionId Discussion id.
* @param {boolean} locked True to pin, false to unpin.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resvoled when done.
* @since 3.7
*/
setPinState(discussionId: number, pinned: boolean, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
const params = {
discussionid: discussionId,
targetstate: pinned ? 1 : 0
};
return site.write('mod_forum_set_pin_state', params);
});
}
/**
* Star or unstar a discussion.
*
* @param {number} discussionId Discussion id.
* @param {boolean} starred True to star, false to unstar.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resvoled when done.
* @since 3.7
*/
toggleFavouriteState(discussionId: number, starred: boolean, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
const params = {
discussionid: discussionId,
targetstate: starred ? 1 : 0
};
return site.write('mod_forum_toggle_favourite_state', params);
});
}
/** /**
* Store the users data from a discussions/posts list. * Store the users data from a discussions/posts list.
* *

View File

@ -478,6 +478,7 @@
"addon.mod_forum.addanewdiscussion": "Add a new discussion topic", "addon.mod_forum.addanewdiscussion": "Add a new discussion topic",
"addon.mod_forum.addanewquestion": "Add a new question", "addon.mod_forum.addanewquestion": "Add a new question",
"addon.mod_forum.addanewtopic": "Add a new topic", "addon.mod_forum.addanewtopic": "Add a new topic",
"addon.mod_forum.addtofavourites": "Star this discussion",
"addon.mod_forum.advanced": "Advanced", "addon.mod_forum.advanced": "Advanced",
"addon.mod_forum.cannotadddiscussion": "Adding discussions to this forum requires group membership.", "addon.mod_forum.cannotadddiscussion": "Adding discussions to this forum requires group membership.",
"addon.mod_forum.cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.", "addon.mod_forum.cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.",
@ -492,9 +493,11 @@
"addon.mod_forum.erroremptysubject": "Post subject cannot be empty.", "addon.mod_forum.erroremptysubject": "Post subject cannot be empty.",
"addon.mod_forum.errorgetforum": "Error getting forum data.", "addon.mod_forum.errorgetforum": "Error getting forum data.",
"addon.mod_forum.errorgetgroups": "Error getting group settings.", "addon.mod_forum.errorgetgroups": "Error getting group settings.",
"addon.mod_forum.favouriteupdated": "Your star option has been updated.",
"addon.mod_forum.forumnodiscussionsyet": "There are no discussions yet in this forum.", "addon.mod_forum.forumnodiscussionsyet": "There are no discussions yet in this forum.",
"addon.mod_forum.group": "Group", "addon.mod_forum.group": "Group",
"addon.mod_forum.locked": "Locked", "addon.mod_forum.locked": "Locked",
"addon.mod_forum.lockupdated": "The lock option has been updated.",
"addon.mod_forum.message": "Message", "addon.mod_forum.message": "Message",
"addon.mod_forum.modeflatnewestfirst": "Display replies flat, with newest first", "addon.mod_forum.modeflatnewestfirst": "Display replies flat, with newest first",
"addon.mod_forum.modeflatoldestfirst": "Display replies flat, with oldest first", "addon.mod_forum.modeflatoldestfirst": "Display replies flat, with oldest first",
@ -503,15 +506,19 @@
"addon.mod_forum.notlocked": "Lock", "addon.mod_forum.notlocked": "Lock",
"addon.mod_forum.numdiscussions": "{{numdiscussions}} discussions", "addon.mod_forum.numdiscussions": "{{numdiscussions}} discussions",
"addon.mod_forum.numreplies": "{{numreplies}} replies", "addon.mod_forum.numreplies": "{{numreplies}} replies",
"addon.mod_forum.pindiscussion": "Pin this discussion",
"addon.mod_forum.pinupdated": "The pin option has been updated.",
"addon.mod_forum.postisprivatereply": "This post was made privately and is not visible to all users.", "addon.mod_forum.postisprivatereply": "This post was made privately and is not visible to all users.",
"addon.mod_forum.posttoforum": "Post to forum", "addon.mod_forum.posttoforum": "Post to forum",
"addon.mod_forum.privatereply": "Reply privately", "addon.mod_forum.privatereply": "Reply privately",
"addon.mod_forum.re": "Re:", "addon.mod_forum.re": "Re:",
"addon.mod_forum.refreshdiscussions": "Refresh discussions", "addon.mod_forum.refreshdiscussions": "Refresh discussions",
"addon.mod_forum.refreshposts": "Refresh posts", "addon.mod_forum.refreshposts": "Refresh posts",
"addon.mod_forum.removefromfavourites": "Unstar this discussion",
"addon.mod_forum.reply": "Reply", "addon.mod_forum.reply": "Reply",
"addon.mod_forum.replyplaceholder": "Write your reply...", "addon.mod_forum.replyplaceholder": "Write your reply...",
"addon.mod_forum.subject": "Subject", "addon.mod_forum.subject": "Subject",
"addon.mod_forum.unpindiscussion": "Unpin this discussion",
"addon.mod_forum.unread": "Unread", "addon.mod_forum.unread": "Unread",
"addon.mod_forum.unreadpostsnumber": "{{$a}} unread posts", "addon.mod_forum.unreadpostsnumber": "{{$a}} unread posts",
"addon.mod_glossary.addentry": "Add a new entry", "addon.mod_glossary.addentry": "Add a new entry",

View File

@ -1,5 +1,3 @@
$core-star-color: $core-color !default;
ion-app.app-root core-courses-course-progress { ion-app.app-root core-courses-course-progress {
ion-card.card { ion-card.card {
display: flex; display: flex;

View File

@ -126,6 +126,7 @@ $popover-width: 280px !default;
$item-divider-background: $gray-lighter !default; $item-divider-background: $gray-lighter !default;
$item-divider-color: $black !default; $item-divider-color: $black !default;
$core-star-color: $core-color !default;
// Moodle Mobile variables // Moodle Mobile variables
// -------------------------------------------------- // --------------------------------------------------