commit
0afc1bb2cb
|
@ -87,7 +87,7 @@ const preferencesRoutes: Routes = [
|
||||||
CoreUserDelegate.registerHandler(AddonMessagesSendMessageUserHandler.instance);
|
CoreUserDelegate.registerHandler(AddonMessagesSendMessageUserHandler.instance);
|
||||||
|
|
||||||
// Sync some discussions when device goes online.
|
// Sync some discussions when device goes online.
|
||||||
CoreNetwork.onConnect().subscribe(() => {
|
CoreNetwork.onConnectShouldBeStable().subscribe(() => {
|
||||||
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
||||||
NgZone.run(() => {
|
NgZone.run(() => {
|
||||||
AddonMessagesSync.syncAllDiscussions(undefined, true);
|
AddonMessagesSync.syncAllDiscussions(undefined, true);
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
<!-- Template to render a list of conversations. -->
|
<!-- Template to render a list of conversations. -->
|
||||||
<ng-template #attemptsTemplate let-attempts="attempts">
|
<ng-template #attemptsTemplate let-attempts="attempts">
|
||||||
<!-- "Header" of the table -->
|
<!-- "Header" of the table -->
|
||||||
<ion-item class="ion-text-wrap addon-mod_h5pactivity-table-header hide-detail" detail="true">
|
<ion-item class="addon-mod_h5pactivity-table-header hide-detail" detail="true">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<ion-row class="ion-align-items-center">
|
<ion-row class="ion-align-items-center">
|
||||||
<ion-col class="ion-text-center">#</ion-col>
|
<ion-col class="ion-text-center">#</ion-col>
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
:host {
|
:host {
|
||||||
.addon-mod_h5pactivity-table-header {
|
.addon-mod_h5pactivity-table-header {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
|
ion-col {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.addon-mod_h5pactivity-table-row .addon-mod_h5pactivity-table-success-col {
|
.addon-mod_h5pactivity-table-row .addon-mod_h5pactivity-table-success-col {
|
||||||
|
|
|
@ -31,9 +31,9 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
<!-- List of users. -->
|
<!-- List of users. -->
|
||||||
<ion-item class="ion-text-wrap addon-mod_h5pactivity-table-row" *ngFor="let user of users" detail="true" button
|
<ion-item class="ion-text-wrap addon-mod_h5pactivity-table-row" *ngFor="let user of users" detail="true"
|
||||||
[attr.aria-label]="'addon.mod_h5pactivity.review_user_attempts' | translate:{$a: user.attempts.length}"
|
[attr.aria-label]="'addon.mod_h5pactivity.review_user_attempts' | translate:{$a: user.attempts.length}"
|
||||||
(click)="openUser(user)">
|
(click)="openUser(user)" [class.hide-detail]="!user.attempts.length" [button]="user.attempts.length > 0">
|
||||||
|
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<ion-row class="ion-align-items-center">
|
<ion-row class="ion-align-items-center">
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
:host {
|
||||||
|
.addon-mod_h5pactivity-table-header ion-col {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ import {
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'page-addon-mod-h5pactivity-users-attempts',
|
selector: 'page-addon-mod-h5pactivity-users-attempts',
|
||||||
templateUrl: 'users-attempts.html',
|
templateUrl: 'users-attempts.html',
|
||||||
|
styleUrls: ['users-attempts.scss'],
|
||||||
})
|
})
|
||||||
export class AddonModH5PActivityUsersAttemptsPage implements OnInit {
|
export class AddonModH5PActivityUsersAttemptsPage implements OnInit {
|
||||||
|
|
||||||
|
@ -208,6 +209,10 @@ export class AddonModH5PActivityUsersAttemptsPage implements OnInit {
|
||||||
* @param user User to open.
|
* @param user User to open.
|
||||||
*/
|
*/
|
||||||
openUser(user: AddonModH5PActivityUserAttemptsFormatted): void {
|
openUser(user: AddonModH5PActivityUserAttemptsFormatted): void {
|
||||||
|
if (!user.attempts.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CoreNavigator.navigate(`../userattempts/${user.userid}`);
|
CoreNavigator.navigate(`../userattempts/${user.userid}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,12 +98,12 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
|
||||||
* Fetch notes.
|
* Fetch notes.
|
||||||
*
|
*
|
||||||
* @param sync When to resync notes.
|
* @param sync When to resync notes.
|
||||||
* @param showErrors When to display errors or not.
|
* @param showSyncErrors When to display sync errors or not.
|
||||||
* @returns Promise with the notes.
|
* @returns Promise with the notes.
|
||||||
*/
|
*/
|
||||||
protected async fetchNotes(sync = false, showErrors = false): Promise<void> {
|
protected async fetchNotes(sync = false, showSyncErrors = false): Promise<void> {
|
||||||
if (sync) {
|
if (sync) {
|
||||||
await this.syncNotes(showErrors);
|
await this.syncNotes(showSyncErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -150,15 +150,15 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
|
||||||
/**
|
/**
|
||||||
* Refresh notes on PTR.
|
* Refresh notes on PTR.
|
||||||
*
|
*
|
||||||
* @param showErrors Whether to display errors or not.
|
* @param showSyncErrors Whether to display sync errors or not.
|
||||||
* @param refresher Refresher instance.
|
* @param refresher Refresher instance.
|
||||||
*/
|
*/
|
||||||
refreshNotes(showErrors: boolean, refresher?: IonRefresher): void {
|
refreshNotes(showSyncErrors: boolean, refresher?: IonRefresher): void {
|
||||||
this.refreshIcon = CoreConstants.ICON_LOADING;
|
this.refreshIcon = CoreConstants.ICON_LOADING;
|
||||||
this.syncIcon = CoreConstants.ICON_LOADING;
|
this.syncIcon = CoreConstants.ICON_LOADING;
|
||||||
|
|
||||||
AddonNotes.invalidateNotes(this.courseId, this.userId).finally(() => {
|
AddonNotes.invalidateNotes(this.courseId, this.userId).finally(() => {
|
||||||
this.fetchNotes(true, showErrors).finally(() => {
|
this.fetchNotes(true, showSyncErrors).finally(() => {
|
||||||
if (refresher) {
|
if (refresher) {
|
||||||
refresher?.complete();
|
refresher?.complete();
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
await AddonNotesOffline.undoDeleteNote(note.id);
|
await AddonNotesOffline.undoDeleteNote(note.id);
|
||||||
this.refreshNotes(true);
|
this.refreshNotes(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -266,16 +266,16 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
|
||||||
/**
|
/**
|
||||||
* Tries to synchronize course notes.
|
* Tries to synchronize course notes.
|
||||||
*
|
*
|
||||||
* @param showErrors Whether to display errors or not.
|
* @param showSyncErrors Whether to display sync errors or not.
|
||||||
* @returns Promise resolved when done.
|
* @returns Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected async syncNotes(showErrors: boolean): Promise<void> {
|
protected async syncNotes(showSyncErrors: boolean): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const result = await AddonNotesSync.syncNotes(this.courseId);
|
const result = await AddonNotesSync.syncNotes(this.courseId);
|
||||||
|
|
||||||
this.showSyncWarnings(result.warnings);
|
this.showSyncWarnings(result.warnings);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (showErrors) {
|
if (showSyncErrors) {
|
||||||
CoreDomUtils.showErrorModalDefault(error, 'core.errorsync', true);
|
CoreDomUtils.showErrorModalDefault(error, 'core.errorsync', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,10 +196,15 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
*/
|
*/
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
if (!this.outlet) {
|
if (!this.outlet) {
|
||||||
|
this.logger.debug('Aftew view init: no outlet found');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.logger.debug('Aftew view init');
|
||||||
|
|
||||||
CoreSubscriptions.once(this.outlet.activateEvents, async () => {
|
CoreSubscriptions.once(this.outlet.activateEvents, async () => {
|
||||||
|
this.logger.debug('Activate event triggered');
|
||||||
await CorePlatform.ready();
|
await CorePlatform.ready();
|
||||||
|
|
||||||
this.logger.debug('Hide splash screen');
|
this.logger.debug('Hide splash screen');
|
||||||
|
@ -213,6 +218,8 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
protected async onPlatformReady(): Promise<void> {
|
protected async onPlatformReady(): Promise<void> {
|
||||||
await CorePlatform.ready();
|
await CorePlatform.ready();
|
||||||
|
|
||||||
|
this.logger.debug('Platform is ready');
|
||||||
|
|
||||||
// Refresh online status when changes.
|
// Refresh online status when changes.
|
||||||
CoreNetwork.onChange().subscribe(() => {
|
CoreNetwork.onChange().subscribe(() => {
|
||||||
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
||||||
|
|
|
@ -16,9 +16,12 @@ import { CoreCronDelegate } from '@services/cron';
|
||||||
import { NgZone } from '@singletons';
|
import { NgZone } from '@singletons';
|
||||||
import { CoreNetwork } from '@services/network';
|
import { CoreNetwork } from '@services/network';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializer function.
|
||||||
|
*/
|
||||||
export default function(): void {
|
export default function(): void {
|
||||||
// When the app is re-connected, start network handlers that were stopped.
|
// When the app is re-connected, start network handlers that were stopped.
|
||||||
CoreNetwork.onConnect().subscribe(() => {
|
CoreNetwork.onConnectShouldBeStable().subscribe(() => {
|
||||||
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
||||||
NgZone.run(() => CoreCronDelegate.startNetworkHandlers());
|
NgZone.run(() => CoreCronDelegate.startNetworkHandlers());
|
||||||
});
|
});
|
||||||
|
|
|
@ -150,7 +150,7 @@ export class CoreFilepoolProvider {
|
||||||
this.checkQueueProcessing();
|
this.checkQueueProcessing();
|
||||||
|
|
||||||
// Start queue when device goes online.
|
// Start queue when device goes online.
|
||||||
CoreNetwork.onConnect().subscribe(() => {
|
CoreNetwork.onConnectShouldBeStable().subscribe(() => {
|
||||||
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
||||||
NgZone.run(() => this.checkQueueProcessing());
|
NgZone.run(() => this.checkQueueProcessing());
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,9 +38,11 @@ export class CoreNetworkService extends Network {
|
||||||
type!: string;
|
type!: string;
|
||||||
|
|
||||||
protected connectObservable = new Subject<'connected'>();
|
protected connectObservable = new Subject<'connected'>();
|
||||||
|
protected connectStableObservable = new Subject<'connected'>();
|
||||||
protected disconnectObservable = new Subject<'disconnected'>();
|
protected disconnectObservable = new Subject<'disconnected'>();
|
||||||
protected forceConnectionMode?: CoreNetworkConnection;
|
protected forceConnectionMode?: CoreNetworkConnection;
|
||||||
protected online = false;
|
protected online = false;
|
||||||
|
protected connectStableTimeout?: number;
|
||||||
|
|
||||||
get connectionType(): CoreNetworkConnection {
|
get connectionType(): CoreNetworkConnection {
|
||||||
if (this.forceConnectionMode !== undefined) {
|
if (this.forceConnectionMode !== undefined) {
|
||||||
|
@ -146,6 +148,7 @@ export class CoreNetworkService extends Network {
|
||||||
/**
|
/**
|
||||||
* Returns an observable to notify when the app is connected.
|
* Returns an observable to notify when the app is connected.
|
||||||
* It will also be fired when connection type changes.
|
* It will also be fired when connection type changes.
|
||||||
|
* If you're going to perform network requests once the device is connected, please use onConnectShouldBeStable instead.
|
||||||
*
|
*
|
||||||
* @returns Observable.
|
* @returns Observable.
|
||||||
*/
|
*/
|
||||||
|
@ -153,6 +156,18 @@ export class CoreNetworkService extends Network {
|
||||||
return this.connectObservable;
|
return this.connectObservable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an observable to notify when the app is connected and it should already be a stable a connection.
|
||||||
|
* E.g. when leaving flight mode the device could connect to mobile network first and then to WiFi.
|
||||||
|
* If you're going to perform network requests once the device is connected, it's recommended to use this function instead of
|
||||||
|
* onConnect because some OS (e.g. Android) duplicate a request if the type of connection changes while the request is done.
|
||||||
|
*
|
||||||
|
* @returns Observable.
|
||||||
|
*/
|
||||||
|
onConnectShouldBeStable(): Observable<'connected'> {
|
||||||
|
return this.connectStableObservable;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an observable to notify when the app is disconnected.
|
* Returns an observable to notify when the app is disconnected.
|
||||||
*
|
*
|
||||||
|
@ -166,10 +181,14 @@ export class CoreNetworkService extends Network {
|
||||||
* Fires the correct observable depending on the connection status.
|
* Fires the correct observable depending on the connection status.
|
||||||
*/
|
*/
|
||||||
protected fireObservable(): void {
|
protected fireObservable(): void {
|
||||||
|
clearTimeout(this.connectStableTimeout);
|
||||||
this.checkOnline();
|
this.checkOnline();
|
||||||
|
|
||||||
if (this.online) {
|
if (this.online) {
|
||||||
this.connectObservable.next('connected');
|
this.connectObservable.next('connected');
|
||||||
|
this.connectStableTimeout = window.setTimeout(() => {
|
||||||
|
this.connectStableObservable.next('connected');
|
||||||
|
}, 5000);
|
||||||
} else {
|
} else {
|
||||||
this.disconnectObservable.next('disconnected');
|
this.disconnectObservable.next('disconnected');
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ export class CoreIframeUtilsProvider {
|
||||||
this.addOfflineWarning(element, src, isSubframe);
|
this.addOfflineWarning(element, src, isSubframe);
|
||||||
|
|
||||||
// If the network changes, check it again.
|
// If the network changes, check it again.
|
||||||
const subscription = CoreNetwork.onConnect().subscribe(() => {
|
const subscription = CoreNetwork.onConnectShouldBeStable().subscribe(() => {
|
||||||
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
||||||
NgZone.run(() => {
|
NgZone.run(() => {
|
||||||
if (!this.checkOnlineFrameInOffline(element, isSubframe)) {
|
if (!this.checkOnlineFrameInOffline(element, isSubframe)) {
|
||||||
|
|
Loading…
Reference in New Issue