MOBILE-3134 core: Debounce calls to update size in activity

main
Dani Palou 2020-04-09 15:25:23 +02:00
parent 254107075b
commit 9f325e163f
28 changed files with 193 additions and 73 deletions

View File

@ -1390,6 +1390,7 @@
"core.course.allsections": "local_moodlemobileapp", "core.course.allsections": "local_moodlemobileapp",
"core.course.askadmintosupport": "local_moodlemobileapp", "core.course.askadmintosupport": "local_moodlemobileapp",
"core.course.availablespace": "local_moodlemobileapp", "core.course.availablespace": "local_moodlemobileapp",
"core.course.cannotdeletewhiledownloading": "local_moodlemobileapp",
"core.course.confirmdeletemodulefiles": "local_moodlemobileapp", "core.course.confirmdeletemodulefiles": "local_moodlemobileapp",
"core.course.confirmdownload": "local_moodlemobileapp", "core.course.confirmdownload": "local_moodlemobileapp",
"core.course.confirmdownloadunknownsize": "local_moodlemobileapp", "core.course.confirmdownloadunknownsize": "local_moodlemobileapp",

View File

@ -7,7 +7,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -9,7 +9,7 @@
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item> <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -7,7 +7,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -12,7 +12,7 @@
<core-context-menu-item [priority]="500" *ngIf="canAdd" [content]="'addon.mod_data.addentries' | translate" [iconAction]="'add'" (action)="gotoAddEntries($event)"></core-context-menu-item> <core-context-menu-item [priority]="500" *ngIf="canAdd" [content]="'addon.mod_data.addentries' | translate" [iconAction]="'add'" (action)="gotoAddEntries($event)"></core-context-menu-item>
<core-context-menu-item [priority]="400" *ngIf="firstEntry" [content]="'addon.mod_data.single' | translate" [iconAction]="'document'" (action)="gotoEntry(firstEntry)"></core-context-menu-item> <core-context-menu-item [priority]="400" *ngIf="firstEntry" [content]="'addon.mod_data.single' | translate" [iconAction]="'document'" (action)="gotoEntry(firstEntry)"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="300" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="300" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="200" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="200" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -7,7 +7,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -6,7 +6,7 @@
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item> <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
<core-context-menu-item *ngIf="!subfolder" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="!subfolder" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -7,7 +7,7 @@
<core-context-menu-item *ngIf="loaded && !(hasOffline || hasOfflineRatings) && isOnline" [priority]="700" [content]="'addon.mod_forum.refreshdiscussions' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && !(hasOffline || hasOfflineRatings) && isOnline" [priority]="700" [content]="'addon.mod_forum.refreshdiscussions' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="sortingAvailable" [priority]="300" [content]="'core.sort' | translate" (action)="showSortOrderSelector($event)" iconAction="fa-sort"></core-context-menu-item> <core-context-menu-item *ngIf="sortingAvailable" [priority]="300" [content]="'core.sort' | translate" (action)="showSortOrderSelector($event)" iconAction="fa-sort"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -14,7 +14,7 @@
<core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="650" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="650" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="canAdd" [priority]="600" [content]="'addon.mod_glossary.addentry' | translate" (action)="openNewEntry()" iconAction="add"></core-context-menu-item> <core-context-menu-item *ngIf="canAdd" [priority]="600" [content]="'addon.mod_glossary.addentry' | translate" (action)="openNewEntry()" iconAction="add"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -9,7 +9,7 @@
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item> <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -7,7 +7,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -6,7 +6,7 @@
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item> <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -7,7 +7,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -6,7 +6,7 @@
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item> <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'fa-newspaper-o'" (action)="gotoBlog($event)"></core-context-menu-item>
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -7,7 +7,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -7,7 +7,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -19,7 +19,7 @@
<core-context-menu-item *ngIf="canEdit && (isOnline || pageIsOffline)" [priority]="590" [content]="'core.edit' | translate" iconAction="create" (action)="goToEditPage()"></core-context-menu-item> <core-context-menu-item *ngIf="canEdit && (isOnline || pageIsOffline)" [priority]="590" [content]="'core.edit' | translate" iconAction="create" (action)="goToEditPage()"></core-context-menu-item>
<core-context-menu-item *ngIf="canEdit" [priority]="580" [content]="'addon.mod_wiki.createpage' | translate" iconAction="add" (action)="goToNewPage()"></core-context-menu-item> <core-context-menu-item *ngIf="canEdit" [priority]="580" [content]="'addon.mod_wiki.createpage' | translate" iconAction="add" (action)="goToNewPage()"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -7,7 +7,7 @@
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item *ngIf="size" [priority]="400" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -1390,6 +1390,7 @@
"core.course.allsections": "All sections", "core.course.allsections": "All sections",
"core.course.askadmintosupport": "Contact the site administrator and tell them you want to use this activity with the Moodle Mobile app.", "core.course.askadmintosupport": "Contact the site administrator and tell them you want to use this activity with the Moodle Mobile app.",
"core.course.availablespace": " You currently have about {{available}} free space.", "core.course.availablespace": " You currently have about {{available}} free space.",
"core.course.cannotdeletewhiledownloading": "Files cannot be deleted while the activity is being downloaded. Please wait for the download to finish.",
"core.course.confirmdeletemodulefiles": "Are you sure you want to delete these files?", "core.course.confirmdeletemodulefiles": "Are you sure you want to delete these files?",
"core.course.confirmdownload": "You are about to download {{size}}.{{availableSpace}} Are you sure you want to continue?", "core.course.confirmdownload": "You are about to download {{size}}.{{availableSpace}} Are you sure you want to continue?",
"core.course.confirmdownloadunknownsize": "It was not possible to calculate the size of the download.{{availableSpace}} Are you sure you want to continue?", "core.course.confirmdownloadunknownsize": "It was not possible to calculate the size of the download.{{availableSpace}} Are you sure you want to continue?",

View File

@ -68,12 +68,6 @@ export class CoreConstants {
static OUTDATED = 'outdated'; static OUTDATED = 'outdated';
static NOT_DOWNLOADABLE = 'notdownloadable'; static NOT_DOWNLOADABLE = 'notdownloadable';
// File status constants.
static FILE_ACTION_DOWNLOAD = 'download';
static FILE_ACTION_DOWNLOADING = 'downloading';
static FILE_ACTION_DELETED = 'deleted';
static FILE_ACTION_OUTDATED = 'outdated';
// Constants from Moodle's resourcelib. // Constants from Moodle's resourcelib.
static RESOURCELIB_DISPLAY_AUTO = 0; // Try the best way. static RESOURCELIB_DISPLAY_AUTO = 0; // Try the best way.
static RESOURCELIB_DISPLAY_EMBED = 1; // Display using object tag. static RESOURCELIB_DISPLAY_EMBED = 1; // Display using object tag.

View File

@ -261,9 +261,17 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
/** /**
* Confirm and remove downloaded files. * Confirm and remove downloaded files.
*
* @param done Function to call when done.
*/ */
removeFiles(): void { removeFiles(done?: () => void): void {
this.courseHelper.confirmAndRemoveFiles(this.module, this.courseId); if (this.prefetchStatus == CoreConstants.DOWNLOADING) {
this.domUtils.showAlertTranslated(null, 'core.course.cannotdeletewhiledownloading');
return;
}
this.courseHelper.confirmAndRemoveFiles(this.module, this.courseId, done);
} }
/** /**

View File

@ -5,6 +5,7 @@
"allsections": "All sections", "allsections": "All sections",
"askadmintosupport": "Contact the site administrator and tell them you want to use this activity with the Moodle Mobile app.", "askadmintosupport": "Contact the site administrator and tell them you want to use this activity with the Moodle Mobile app.",
"availablespace": " You currently have about {{available}} free space.", "availablespace": " You currently have about {{available}} free space.",
"cannotdeletewhiledownloading": "Files cannot be deleted while the activity is being downloaded. Please wait for the download to finish.",
"confirmdeletemodulefiles": "Are you sure you want to delete these files?", "confirmdeletemodulefiles": "Are you sure you want to delete these files?",
"confirmdownload": "You are about to download {{size}}.{{availableSpace}} Are you sure you want to continue?", "confirmdownload": "You are about to download {{size}}.{{availableSpace}} Are you sure you want to continue?",
"confirmdownloadunknownsize": "It was not possible to calculate the size of the download.{{availableSpace}} Are you sure you want to continue?", "confirmdownloadunknownsize": "It was not possible to calculate the size of the download.{{availableSpace}} Are you sure you want to continue?",

View File

@ -13,12 +13,12 @@
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
import { NavController } from 'ionic-angular'; import { NavController, Loading } from 'ionic-angular';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app'; import { CoreAppProvider } from '@providers/app';
import { CoreEventsProvider } from '@providers/events'; import { CoreEventsProvider } from '@providers/events';
import { CoreFileProvider } from '@providers/file'; import { CoreFileProvider } from '@providers/file';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider, CoreFilepoolComponentFileEventData } from '@providers/filepool';
import { CoreFileHelperProvider } from '@providers/file-helper'; import { CoreFileHelperProvider } from '@providers/file-helper';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreDomUtilsProvider } from '@providers/utils/dom';
@ -408,16 +408,29 @@ export class CoreCourseHelperProvider {
* *
* @param module Module to remove the files. * @param module Module to remove the files.
* @param courseId Course ID the module belongs to. * @param courseId Course ID the module belongs to.
* @param done Function to call when done. It will close the context menu.
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
confirmAndRemoveFiles(module: any, courseId: number): Promise<any> { async confirmAndRemoveFiles(module: any, courseId: number, done?: () => void): Promise<void> {
return this.domUtils.showDeleteConfirm('core.course.confirmdeletemodulefiles').then(() => { let modal: Loading;
return this.prefetchDelegate.removeModuleFiles(module, courseId);
}).catch((error) => { try {
await this.domUtils.showDeleteConfirm('core.course.confirmdeletemodulefiles');
modal = this.domUtils.showModalLoading();
await this.prefetchDelegate.removeModuleFiles(module, courseId);
done && done();
} catch (error) {
if (error) { if (error) {
this.domUtils.showErrorModal(error); this.domUtils.showErrorModal(error);
} }
}); } finally {
modal && modal.dismiss();
}
} }
/** /**
@ -831,15 +844,27 @@ export class CoreCourseHelperProvider {
} }
if (typeof instance.contextFileStatusObserver == 'undefined' && component) { if (typeof instance.contextFileStatusObserver == 'undefined' && component) {
const componentFileChangeStatusEvent = CoreFilepoolProvider.getComponentEventName(siteId, component, module.id); // Debounce the update size function to prevent too many calls when downloading or deleting a whole activity.
const debouncedUpdateSize = this.utils.debounce(() => {
this.prefetchDelegate.getModuleDownloadedSize(module, courseId).then((moduleSize) => {
instance.size = moduleSize > 0 ? this.textUtils.bytesToSize(moduleSize, 2) : 0;
});
}, 1000);
instance.contextFileStatusObserver = this.eventsProvider.on(componentFileChangeStatusEvent, (data) => { instance.contextFileStatusObserver = this.eventsProvider.on(CoreEventsProvider.COMPONENT_FILE_ACTION,
(data: CoreFilepoolComponentFileEventData) => {
if (((data.action == CoreConstants.FILE_ACTION_DOWNLOAD && data.success == true) || if (data.component != component || data.componentId != module.id) {
data.action == CoreConstants.FILE_ACTION_DELETED) && // The event doesn't belong to this component, ignore.
instance.prefetchStatus != CoreConstants.DOWNLOADING) { return;
this.fillContextMenu(instance, module, courseId, true, component);
} }
if (!this.filepoolProvider.isFileEventDownloadedOrDeleted(data)) {
return;
}
// Update the module size.
debouncedUpdateSize();
}, siteId); }, siteId);
} }
}); });

View File

@ -15,7 +15,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreEventsProvider } from '@providers/events'; import { CoreEventsProvider } from '@providers/events';
import { CoreFileProvider } from '@providers/file'; import { CoreFileProvider } from '@providers/file';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider, CoreFilepoolComponentFileEventData } from '@providers/filepool';
import { CoreLoggerProvider } from '@providers/logger'; import { CoreLoggerProvider } from '@providers/logger';
import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites';
import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreTimeUtilsProvider } from '@providers/utils/time';
@ -276,6 +276,15 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate {
eventsProvider.on(CoreEventsProvider.PACKAGE_STATUS_CHANGED, (data) => { eventsProvider.on(CoreEventsProvider.PACKAGE_STATUS_CHANGED, (data) => {
this.updateStatusCache(data.status, data.component, data.componentId); this.updateStatusCache(data.status, data.component, data.componentId);
}, this.sitesProvider.getCurrentSiteId()); }, this.sitesProvider.getCurrentSiteId());
// If a file inside a module is downloaded/deleted, clear the corresponding cache.
eventsProvider.on(CoreEventsProvider.COMPONENT_FILE_ACTION, (data: CoreFilepoolComponentFileEventData) => {
if (!this.filepoolProvider.isFileEventDownloadedOrDeleted(data)) {
return;
}
this.statusCache.invalidate(this.filepoolProvider.getPackageId(data.component, data.componentId));
}, this.sitesProvider.getCurrentSiteId());
} }
/** /**

View File

@ -5,7 +5,7 @@
<core-context-menu-item [hidden]="!displayDescription || !description || (content && content.compileComponent && content.compileComponent.componentInstance && content.compileComponent.componentInstance.displayDescription === false)" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item> <core-context-menu-item [hidden]="!displayDescription || !description || (content && content.compileComponent && content.compileComponent.componentInstance && content.compileComponent.componentInstance.displayDescription === false)" [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" [iconAction]="'arrow-forward'"></core-context-menu-item>
<core-context-menu-item [hidden]="!displayRefresh || (content && content.compileComponent && content.compileComponent.componentInstance && content.compileComponent.componentInstance.displayRefresh === false)" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item [hidden]="!displayRefresh || (content && content.compileComponent && content.compileComponent.componentInstance && content.compileComponent.componentInstance.displayRefresh === false)" [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item [hidden]="!displayPrefetch || !prefetchStatusIcon || (content && content.compileComponent && content.compileComponent.componentInstance && content.compileComponent.componentInstance.displayPrefetch === false)" [priority]="600" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item [hidden]="!displayPrefetch || !prefetchStatusIcon || (content && content.compileComponent && content.compileComponent.componentInstance && content.compileComponent.componentInstance.displayPrefetch === false)" [priority]="600" [content]="prefetchText" (action)="prefetch()" [iconAction]="prefetchStatusIcon" [closeOnClick]="false"></core-context-menu-item>
<core-context-menu-item [hidden]="!displaySize || !size || (content && content.compileComponent && content.compileComponent.componentInstance && content.compileComponent.componentInstance.displaySize === false)" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" [iconAction]="'trash'"></core-context-menu-item> <core-context-menu-item [hidden]="!displaySize || !size || (content && content.compileComponent && content.compileComponent.componentInstance && content.compileComponent.componentInstance.displaySize === false)" [priority]="500" [content]="'core.removefiles' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles($event)" [iconAction]="'trash'" [closeOnClick]="false"></core-context-menu-item>
</core-context-menu> </core-context-menu>
</core-navbar-buttons> </core-navbar-buttons>

View File

@ -47,6 +47,7 @@ export class CoreEventsProvider {
static PACKAGE_STATUS_CHANGED = 'package_status_changed'; static PACKAGE_STATUS_CHANGED = 'package_status_changed';
static COURSE_STATUS_CHANGED = 'course_status_changed'; static COURSE_STATUS_CHANGED = 'course_status_changed';
static SECTION_STATUS_CHANGED = 'section_status_changed'; static SECTION_STATUS_CHANGED = 'section_status_changed';
static COMPONENT_FILE_ACTION = 'component_file_action';
static SITE_PLUGINS_LOADED = 'site_plugins_loaded'; static SITE_PLUGINS_LOADED = 'site_plugins_loaded';
static SITE_PLUGINS_COURSE_RESTRICT_UPDATED = 'site_plugins_course_restrict_updated'; static SITE_PLUGINS_COURSE_RESTRICT_UPDATED = 'site_plugins_course_restrict_updated';
static LOGIN_SITE_CHECKED = 'login_site_checked'; static LOGIN_SITE_CHECKED = 'login_site_checked';

View File

@ -212,6 +212,51 @@ export interface CoreFilepoolComponentLink {
componentId?: string | number; componentId?: string | number;
} }
/**
* File actions.
*/
export const enum CoreFilepoolFileActions {
DOWNLOAD = 'download',
DOWNLOADING = 'downloading',
DELETED = 'deleted',
OUTDATED = 'outdated',
}
/**
* Data sent to file events.
*/
export interface CoreFilepoolFileEventData {
/**
* The file ID.
*/
fileId: string;
/**
* The file ID.
*/
action: CoreFilepoolFileActions;
/**
* Whether the action was a success. Only for DOWNLOAD action.
*/
success?: boolean;
}
/**
* Data sent to component file events.
*/
export interface CoreFilepoolComponentFileEventData extends CoreFilepoolFileEventData {
/**
* The component.
*/
component: string;
/**
* The component ID.
*/
componentId: string | number;
}
/* /*
* Factory for handling downloading files and retrieve downloaded files. * Factory for handling downloading files and retrieve downloaded files.
* *
@ -1218,8 +1263,9 @@ export class CoreFilepoolProvider {
downloadUrl(siteId: string, fileUrl: string, ignoreStale?: boolean, component?: string, componentId?: string | number, downloadUrl(siteId: string, fileUrl: string, ignoreStale?: boolean, component?: string, componentId?: string | number,
timemodified: number = 0, onProgress?: (event: any) => any, filePath?: string, options: any = {}, revision?: number) timemodified: number = 0, onProgress?: (event: any) => any, filePath?: string, options: any = {}, revision?: number)
: Promise<any> { : Promise<any> {
let fileId, let fileId;
promise; let promise;
let alreadyDownloaded = true;
if (this.fileProvider.isAvailable()) { if (this.fileProvider.isAvailable()) {
return this.fixPluginfileURL(siteId, fileUrl).then((file) => { return this.fixPluginfileURL(siteId, fileUrl).then((file) => {
@ -1239,6 +1285,7 @@ export class CoreFilepoolProvider {
if (typeof fileObject === 'undefined') { if (typeof fileObject === 'undefined') {
// We do not have the file, download and add to pool. // We do not have the file, download and add to pool.
this.notifyFileDownloading(siteId, fileId, links); this.notifyFileDownloading(siteId, fileId, links);
alreadyDownloaded = false;
return this.downloadForPoolByUrl(siteId, fileUrl, options, filePath, onProgress); return this.downloadForPoolByUrl(siteId, fileUrl, options, filePath, onProgress);
@ -1246,6 +1293,7 @@ export class CoreFilepoolProvider {
this.appProvider.isOnline() && !ignoreStale) { this.appProvider.isOnline() && !ignoreStale) {
// The file is outdated, force the download and update it. // The file is outdated, force the download and update it.
this.notifyFileDownloading(siteId, fileId, links); this.notifyFileDownloading(siteId, fileId, links);
alreadyDownloaded = false;
return this.downloadForPoolByUrl(siteId, fileUrl, options, filePath, onProgress, fileObject); return this.downloadForPoolByUrl(siteId, fileUrl, options, filePath, onProgress, fileObject);
} }
@ -1262,6 +1310,7 @@ export class CoreFilepoolProvider {
}, () => { }, () => {
// The file was not found in the pool, weird. // The file was not found in the pool, weird.
this.notifyFileDownloading(siteId, fileId, links); this.notifyFileDownloading(siteId, fileId, links);
alreadyDownloaded = false;
return this.downloadForPoolByUrl(siteId, fileUrl, options, filePath, onProgress, fileObject); return this.downloadForPoolByUrl(siteId, fileUrl, options, filePath, onProgress, fileObject);
}); });
@ -1269,6 +1318,7 @@ export class CoreFilepoolProvider {
}, () => { }, () => {
// The file is not in the pool just yet. // The file is not in the pool just yet.
this.notifyFileDownloading(siteId, fileId, links); this.notifyFileDownloading(siteId, fileId, links);
alreadyDownloaded = false;
return this.downloadForPoolByUrl(siteId, fileUrl, options, filePath, onProgress); return this.downloadForPoolByUrl(siteId, fileUrl, options, filePath, onProgress);
}).then((response) => { }).then((response) => {
@ -1277,7 +1327,10 @@ export class CoreFilepoolProvider {
// Ignore errors. // Ignore errors.
}); });
} }
if (!alreadyDownloaded) {
this.notifyFileDownloaded(siteId, fileId, links); this.notifyFileDownloaded(siteId, fileId, links);
}
return response; return response;
}, (err) => { }, (err) => {
@ -1434,18 +1487,6 @@ export class CoreFilepoolProvider {
}); });
} }
/**
* Get the name of the event used to notify file status to component (CoreEventsProvider).
*
* @param siteId The site ID.
* @param component The component name.
* @param componentId The component ID.
* @return Event name.
*/
static getComponentEventName(siteId: string, component: string, componentId: string | number): string {
return 'CoreFilepoolComponentFile:' + siteId + ':' + component + ':' + componentId;
}
/** /**
* Convenience function to get component files. * Convenience function to get component files.
* *
@ -2450,6 +2491,17 @@ export class CoreFilepoolProvider {
}); });
} }
/**
* Whether a file action indicates a file was downloaded or deleted.
*
* @param data Event data.
* @return Whether downloaded or deleted.
*/
isFileEventDownloadedOrDeleted(data: CoreFilepoolFileEventData): boolean {
return (data.action == CoreFilepoolFileActions.DOWNLOAD && data.success == true) ||
data.action == CoreFilepoolFileActions.DELETED;
}
/** /**
* Check whether a file is downloadable. * Check whether a file is downloadable.
* *
@ -2508,14 +2560,19 @@ export class CoreFilepoolProvider {
* Notify an action performed on a file to a list of components. * Notify an action performed on a file to a list of components.
* *
* @param siteId The site ID. * @param siteId The site ID.
* @param eventData The event data. * @param eventData The file event data.
* @param links The links to the components. * @param links The links to the components.
*/ */
protected notifyFileActionToComponents(siteId: string, eventData: any, links: CoreFilepoolComponentLink[]): void { protected notifyFileActionToComponents(siteId: string, eventData: CoreFilepoolFileEventData,
links: CoreFilepoolComponentLink[]): void {
links.forEach((link) => { links.forEach((link) => {
this.eventsProvider.trigger(CoreFilepoolProvider.getComponentEventName(siteId, link.component, link.componentId), const data: CoreFilepoolComponentFileEventData = Object.assign({
eventData, siteId); component: link.component,
componentId: link.componentId,
}, eventData);
this.eventsProvider.trigger(CoreEventsProvider.COMPONENT_FILE_ACTION, data, siteId);
}); });
} }
@ -2527,9 +2584,9 @@ export class CoreFilepoolProvider {
* @param links The links to components. * @param links The links to components.
*/ */
protected notifyFileDeleted(siteId: string, fileId: string, links: CoreFilepoolComponentLink[]): void { protected notifyFileDeleted(siteId: string, fileId: string, links: CoreFilepoolComponentLink[]): void {
const data = { const data: CoreFilepoolFileEventData = {
fileId: fileId, fileId: fileId,
action: CoreConstants.FILE_ACTION_DELETED action: CoreFilepoolFileActions.DELETED,
}; };
this.eventsProvider.trigger(this.getFileEventName(siteId, fileId), data); this.eventsProvider.trigger(this.getFileEventName(siteId, fileId), data);
@ -2544,10 +2601,10 @@ export class CoreFilepoolProvider {
* @param links The links to components. * @param links The links to components.
*/ */
protected notifyFileDownloaded(siteId: string, fileId: string, links: CoreFilepoolComponentLink[]): void { protected notifyFileDownloaded(siteId: string, fileId: string, links: CoreFilepoolComponentLink[]): void {
const data = { const data: CoreFilepoolFileEventData = {
fileId: fileId, fileId: fileId,
action: CoreConstants.FILE_ACTION_DOWNLOAD, action: CoreFilepoolFileActions.DOWNLOAD,
success: true success: true,
}; };
this.eventsProvider.trigger(this.getFileEventName(siteId, fileId), data); this.eventsProvider.trigger(this.getFileEventName(siteId, fileId), data);
@ -2562,10 +2619,10 @@ export class CoreFilepoolProvider {
* @param links The links to components. * @param links The links to components.
*/ */
protected notifyFileDownloadError(siteId: string, fileId: string, links: CoreFilepoolComponentLink[]): void { protected notifyFileDownloadError(siteId: string, fileId: string, links: CoreFilepoolComponentLink[]): void {
const data = { const data: CoreFilepoolFileEventData = {
fileId: fileId, fileId: fileId,
action: CoreConstants.FILE_ACTION_DOWNLOAD, action: CoreFilepoolFileActions.DOWNLOAD,
success: false success: false,
}; };
this.eventsProvider.trigger(this.getFileEventName(siteId, fileId), data); this.eventsProvider.trigger(this.getFileEventName(siteId, fileId), data);
@ -2580,9 +2637,9 @@ export class CoreFilepoolProvider {
* @param links The links to components. * @param links The links to components.
*/ */
protected notifyFileDownloading(siteId: string, fileId: string, links: CoreFilepoolComponentLink[]): void { protected notifyFileDownloading(siteId: string, fileId: string, links: CoreFilepoolComponentLink[]): void {
const data = { const data: CoreFilepoolFileEventData = {
fileId: fileId, fileId: fileId,
action: CoreConstants.FILE_ACTION_DOWNLOADING action: CoreFilepoolFileActions.DOWNLOADING,
}; };
this.eventsProvider.trigger(this.getFileEventName(siteId, fileId), data); this.eventsProvider.trigger(this.getFileEventName(siteId, fileId), data);
@ -2598,8 +2655,9 @@ export class CoreFilepoolProvider {
* @param links The links to components. * @param links The links to components.
*/ */
protected notifyFileOutdated(siteId: string, fileId: string, links: CoreFilepoolComponentLink[]): void { protected notifyFileOutdated(siteId: string, fileId: string, links: CoreFilepoolComponentLink[]): void {
const data = { const data: CoreFilepoolFileEventData = {
action: CoreConstants.FILE_ACTION_OUTDATED fileId: fileId,
action: CoreFilepoolFileActions.OUTDATED,
}; };
this.eventsProvider.trigger(this.getFileEventName(siteId, fileId), data); this.eventsProvider.trigger(this.getFileEventName(siteId, fileId), data);
@ -2729,7 +2787,6 @@ export class CoreFilepoolProvider {
}).finally(() => { }).finally(() => {
this.treatQueueDeferred(siteId, fileId, true); this.treatQueueDeferred(siteId, fileId, true);
}); });
this.notifyFileDownloaded(siteId, fileId, links);
return; return;
} }

View File

@ -1392,4 +1392,27 @@ export class CoreUtilsProvider {
return filtered; return filtered;
} }
/**
* Debounce a function so consecutive calls are ignored until a certain time has passed since the last call.
*
* @param context The context to apply to the function.
* @param fn Function to debounce.
* @param delay Time that must pass until the function is called.
* @return Debounced function.
*/
debounce(fn: (...args: any[]) => any, delay: number): (...args: any[]) => void {
let timeoutID: number;
const debounced = (...args: any[]): void => {
clearTimeout(timeoutID);
timeoutID = window.setTimeout(() => {
fn.apply(null, args);
}, delay);
};
return debounced;
}
} }