Skip to content

Commit 39afdb2

Browse files
committed
MOBILE-5003 forum: Apply some UX changes
1 parent ce33db2 commit 39afdb2

7 files changed

Lines changed: 102 additions & 44 deletions

File tree

scripts/langindex.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,10 @@
688688
"addon.mod_forum.modeflatoldestfirst": "forum",
689689
"addon.mod_forum.modenested": "forum",
690690
"addon.mod_forum.modulenameplural": "forum",
691+
"addon.mod_forum.noactionsavailable": "local_moodlemobileapp",
692+
"addon.mod_forum.nopermissiontoact": "local_moodlemobileapp",
691693
"addon.mod_forum.numreplies": "local_moodlemobileapp",
694+
"addon.mod_forum.offlinereconnectactions": "local_moodlemobileapp",
692695
"addon.mod_forum.pindiscussion": "forum",
693696
"addon.mod_forum.pinupdated": "forum",
694697
"addon.mod_forum.postaddedsuccess": "forum",
@@ -699,6 +702,7 @@
699702
"addon.mod_forum.privatereply": "forum",
700703
"addon.mod_forum.qandanotify": "forum",
701704
"addon.mod_forum.re": "forum",
705+
"addon.mod_forum.reconnecttomanage": "local_moodlemobileapp",
702706
"addon.mod_forum.refreshposts": "local_moodlemobileapp",
703707
"addon.mod_forum.removefromfavourites": "forum",
704708
"addon.mod_forum.reply": "forum",

src/addons/mod/forum/components/post-options-menu/post-options-menu.html

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<core-loading [hideUntil]="loaded()" [fullscreen]="false">
33
<ion-list>
44
@if (canMarkAsRead()) {
5-
<ion-item button class="ion-text-wrap" (click)="toggleReadState()" [detail]="false">
5+
<ion-item button class="ion-text-wrap" (click)="toggleReadState()" [detail]="false" [disabled]="markAsReadDisabled()">
66
<ion-icon name="fas-bookmark" slot="start" aria-hidden="true" />
77
<ion-label>
88
<p class="item-heading">
@@ -16,15 +16,15 @@
1616
</ion-item>
1717
}
1818
@if (canEdit()) {
19-
<ion-item button class="ion-text-wrap" (click)="editPost()" [detail]="false">
19+
<ion-item button class="ion-text-wrap" (click)="editPost()" [detail]="false" [disabled]="editDeleteDisabled()">
2020
<ion-icon name="fas-pen" slot="start" aria-hidden="true" />
2121
<ion-label>
2222
<p class="item-heading">{{ 'addon.mod_forum.edit' | translate }}</p>
2323
</ion-label>
2424
</ion-item>
2525
}
2626
@if (canDelete()) {
27-
<ion-item button class="ion-text-wrap" (click)="deletePost()" [detail]="false">
27+
<ion-item button class="ion-text-wrap" (click)="deletePost()" [detail]="false" [disabled]="editDeleteDisabled()">
2828
<ion-icon name="fas-trash" slot="start" aria-hidden="true" />
2929
<ion-label>
3030
<p class="item-heading">
@@ -37,6 +37,32 @@
3737
</ion-label>
3838
</ion-item>
3939
}
40+
41+
@if (!isOnline()) {
42+
@if (unknownCapabilities()) {
43+
<ion-item lines="none" class="ion-text-wrap">
44+
<ion-icon name="fas-lock" slot="start" aria-hidden="true" />
45+
<ion-label>
46+
<p class="item-heading">{{ 'core.youreoffline' | translate }}</p>
47+
<p>{{ 'addon.mod_forum.reconnecttomanage' | translate }}</p>
48+
</ion-label>
49+
</ion-item>
50+
} @else if (!isOfflinePost()) {
51+
<ion-item lines="none" class="ion-text-wrap item-lines-top">
52+
<ion-label>
53+
<p>{{ 'addon.mod_forum.offlinereconnectactions' | translate }}</p>
54+
</ion-label>
55+
</ion-item>
56+
}
57+
} @else if (!canMarkAsRead() && !canEdit() && !canDelete()) {
58+
<ion-item lines="none" class="ion-text-wrap">
59+
<ion-icon name="fas-lock" slot="start" aria-hidden="true" />
60+
<ion-label>
61+
<p class="item-heading">{{ 'addon.mod_forum.noactionsavailable' | translate }}</p>
62+
<p>{{ 'addon.mod_forum.nopermissiontoact' | translate }}</p>
63+
</ion-label>
64+
</ion-item>
65+
}
4066
</ion-list>
4167
</core-loading>
4268
</ion-content>

src/addons/mod/forum/components/post-options-menu/post-options-menu.ts

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
import { Component, OnInit, computed, effect, input, linkedSignal, signal } from '@angular/core';
15+
import { Component, computed, effect, input, linkedSignal, signal, untracked } from '@angular/core';
1616
import { CoreSitesReadingStrategy } from '@services/sites';
1717
import { CoreNetwork } from '@services/network';
1818
import { AddonModForum, AddonModForumPost } from '@addons/mod/forum/services/forum';
@@ -32,64 +32,83 @@ import { AddonModForumHelper } from '../../services/forum-helper';
3232
CoreSharedModule,
3333
],
3434
})
35-
export class AddonModForumPostOptionsMenuComponent implements OnInit {
35+
export class AddonModForumPostOptionsMenuComponent {
3636

3737
readonly post = input.required<AddonModForumPost>(); // The post.
3838
readonly cmId = input.required<number>();
3939
readonly forumId = input.required<number>(); // The forum Id.
4040

4141
protected readonly postCalculated = linkedSignal(() => this.post());
42-
readonly canEdit = computed(() => this.isOfflinePost() ||
43-
(AddonModForumHelper.canUpdatePost(this.postCalculated()) && this.isOnline()));
42+
readonly canEdit = computed(() => this.isOfflinePost() || AddonModForumHelper.canUpdatePost(this.postCalculated()));
4443

45-
readonly canDelete = computed(() => this.isOfflinePost() ||
46-
(AddonModForumHelper.canDeletePost(this.postCalculated()) && this.isOnline()));
44+
readonly canDelete = computed(() => this.isOfflinePost() || AddonModForumHelper.canDeletePost(this.postCalculated()));
45+
readonly editDeleteDisabled = computed(() => this.unknownCapabilities() || (!this.isOfflinePost() && !this.isOnline()));
4746

4847
readonly canMarkAsRead = computed(() =>
49-
!this.isOfflinePost() && AddonModForumHelper.canSetReadState(this.postCalculated()) && this.isOnline());
48+
!this.isOfflinePost() && AddonModForumHelper.canSetReadState(this.postCalculated()));
49+
50+
readonly markAsReadDisabled = computed(() => this.unknownCapabilities() || !this.isOnline());
5051

5152
readonly loaded = signal(false);
5253

5354
readonly isOfflinePost = computed(() => this.postCalculated().id < 0);
5455
protected readonly isOnline = CoreNetwork.onlineSignal;
5556

56-
constructor() {
57-
effect(() => {
58-
// Dismiss the modal to prevent having an empty menu.
59-
if(!this.canDelete() && !this.canEdit() && !this.canMarkAsRead()) {
60-
this.dismiss();
61-
}
62-
});
63-
}
57+
protected readonly unknownCapabilities = computed(() => {
58+
if (this.isOfflinePost()) {
59+
return false;
60+
}
61+
62+
const post = this.postCalculated();
63+
64+
return post.capabilities.delete === undefined;
65+
});
6466

6567
/**
6668
* @inheritdoc
6769
*/
68-
async ngOnInit(): Promise<void> {
69-
if (this.isOfflinePost()) {
70-
this.loaded.set(true);
70+
constructor() {
71+
effect(async () => {
72+
const unknownCapabilities = this.unknownCapabilities();
73+
const isOnline = this.isOnline();
7174

72-
return;
73-
}
75+
if (!unknownCapabilities) {
76+
this.loaded.set(true);
77+
78+
return;
79+
}
80+
81+
// Only check this one because the others are always available if this one is.
82+
const wsAvailable = AddonModForum.isDeletePostAvailable();
83+
if (!wsAvailable) {
84+
// If the WS is not available, we cannot do anything.
85+
this.loaded.set(true);
86+
87+
return;
88+
}
7489

75-
let post = this.postCalculated();
76-
if (post.capabilities.delete === undefined) {
7790
const forumId = this.forumId();
78-
if (forumId) {
79-
try {
80-
post =
81-
await AddonModForum.getDiscussionPost(forumId, post.discussionid, post.id, {
82-
cmId: this.cmId(),
83-
readingStrategy: CoreSitesReadingStrategy.ONLY_NETWORK,
84-
});
85-
this.postCalculated.set(post);
86-
} catch (error) {
87-
CoreAlerts.showError(error, { default: 'Error getting discussion post.' });
88-
}
91+
if (forumId && isOnline) {
92+
this.loaded.set(false);
93+
94+
await untracked(async () => {
95+
let post = this.postCalculated();
96+
97+
try {
98+
post =
99+
await AddonModForum.getDiscussionPost(forumId, post.discussionid, post.id, {
100+
cmId: this.cmId(),
101+
readingStrategy: CoreSitesReadingStrategy.ONLY_NETWORK,
102+
});
103+
this.postCalculated.set(post);
104+
} catch (error) {
105+
CoreAlerts.showError(error, { default: 'Error getting discussion post.' });
106+
}
107+
});
89108
}
90-
}
91109

92-
this.loaded.set(true);
110+
this.loaded.set(true);
111+
});
93112
}
94113

95114
/**

src/addons/mod/forum/lang.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@
4747
"modeflatoldestfirst": "Display replies flat, with oldest first",
4848
"modenested": "Display replies in nested form",
4949
"modulenameplural": "Forums",
50+
"noactionsavailable": "No actions available",
51+
"nopermissiontoact": "You don't have permission to act on this post.",
5052
"numreplies": "{{numreplies}} replies",
53+
"offlinereconnectactions": "You're offline. Reconnect to use these actions.",
5154
"pindiscussion": "Pin this discussion",
5255
"pinupdated": "The pin option has been updated.",
5356
"postaddedsuccess": "Your post was successfully added.",
@@ -58,6 +61,7 @@
5861
"privatereply": "Reply privately",
5962
"qandanotify": "This is a question and answer forum. To see other replies, you must first post your reply.",
6063
"re": "Re:",
64+
"reconnecttomanage": "Reconnect to manage this post.",
6165
"refreshposts": "Refresh posts",
6266
"removefromfavourites": "Unstar this discussion",
6367
"reply": "Reply",

src/addons/mod/forum/tests/behat/basic_usage.feature

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,10 @@ Feature: Test basic usage of forum activity in app
173173
And I press "Cancel" in the app
174174
And I press "OK" in the app
175175
And I press "Display options" within "Auto-test" "ion-card-header" in the app
176-
And I should not find "Edit" in the app
176+
And I should not be able to press "Edit" in the app
177+
And I should find "You're offline. Reconnect to use these actions." in the app
177178

178179
When I switch network connection to wifi
179-
And I press "Display options" within "Auto-test" "ion-card-header" in the app
180180
And I press "Edit" in the app
181181
And I set the field "Message" to "Auto-test message edited" in the app
182182
And I press "Save changes" in the app
@@ -197,10 +197,10 @@ Feature: Test basic usage of forum activity in app
197197
And I press "Cancel" in the app
198198
And I switch network connection to offline
199199
And I press "Display options" within "Auto-test" "ion-card-header" in the app
200-
Then I should not find "Delete" in the app
200+
Then I should not be able to press "Delete" in the app
201+
And I should find "You're offline. Reconnect to use these actions." in the app
201202

202203
And I switch network connection to wifi
203-
And I press "Display options" within "Auto-test" "ion-card-header" in the app
204204
And I press "Delete" in the app
205205
And I press "Delete" in the app
206206
Then I should not find "Auto-test" in the app

src/core/lang.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,8 @@
414414
"year": "year",
415415
"years": "years",
416416
"yes": "Yes",
417-
"youreoffline": "Your device is offline",
418-
"youreonline": "Your device is back online",
417+
"youreoffline": "You're offline",
418+
"youreonline": "You're back online",
419419
"zoomin": "Zoom In",
420420
"zoomout": "Zoom Out"
421421
}

src/theme/components/ion-item.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ ion-item.item {
2626
border-bottom: 1px solid var(--border-color);
2727
}
2828

29+
&.item-lines-top {
30+
--inner-border-width: 0px;
31+
--border-width: 1px 0 0 0;
32+
}
33+
2934
&.item-lines-default,
3035
&.item-has-interactive-control {
3136
/** Remove lines by default and interactive control (toggles, radios, checkbox and selects) */

0 commit comments

Comments
 (0)