commit
fbf495ca1b
|
@ -77,7 +77,6 @@
|
||||||
"cordova-plugin-media-capture": "^3.0.3",
|
"cordova-plugin-media-capture": "^3.0.3",
|
||||||
"cordova-plugin-network-information": "^2.0.2",
|
"cordova-plugin-network-information": "^2.0.2",
|
||||||
"cordova-plugin-prevent-override": "^1.0.0",
|
"cordova-plugin-prevent-override": "^1.0.0",
|
||||||
"cordova-plugin-screen-orientation": "^3.0.2",
|
|
||||||
"cordova-plugin-splashscreen": "^6.0.0",
|
"cordova-plugin-splashscreen": "^6.0.0",
|
||||||
"cordova-plugin-statusbar": "^2.4.3",
|
"cordova-plugin-statusbar": "^2.4.3",
|
||||||
"cordova-plugin-whitelist": "^1.3.4",
|
"cordova-plugin-whitelist": "^1.3.4",
|
||||||
|
@ -11201,18 +11200,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cordova-plugin-screen-orientation": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/cordova-plugin-screen-orientation/-/cordova-plugin-screen-orientation-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-2w6CMC+HGvbhogJetalwGurL2Fx8DQCCPy3wlSZHN1/W7WoQ5n9ujVozcoKrY4VaagK6bxrPFih+ElkO8Uqfzg==",
|
|
||||||
"engines": {
|
|
||||||
"cordovaDependencies": {
|
|
||||||
"4.0.0": {
|
|
||||||
"cordova": ">100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cordova-plugin-splashscreen": {
|
"node_modules/cordova-plugin-splashscreen": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cordova-plugin-splashscreen/-/cordova-plugin-splashscreen-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cordova-plugin-splashscreen/-/cordova-plugin-splashscreen-6.0.0.tgz",
|
||||||
|
@ -12799,6 +12786,7 @@
|
||||||
"version": "0.1.13",
|
"version": "0.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
||||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
||||||
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"iconv-lite": "^0.6.2"
|
"iconv-lite": "^0.6.2"
|
||||||
}
|
}
|
||||||
|
@ -12807,6 +12795,7 @@
|
||||||
"version": "0.6.2",
|
"version": "0.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
|
||||||
"integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
|
"integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
|
||||||
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
},
|
},
|
||||||
|
@ -39888,11 +39877,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/cordova-plugin-prevent-override/-/cordova-plugin-prevent-override-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cordova-plugin-prevent-override/-/cordova-plugin-prevent-override-1.0.0.tgz",
|
||||||
"integrity": "sha512-/+3q5r4K5RahCpiYVmZQBjq10x4jj+6CMjYtZyx9jdMWeV+yFE+ItFcO1NeUAEWd2iHC5YPD0P2tHiHx5kscsw=="
|
"integrity": "sha512-/+3q5r4K5RahCpiYVmZQBjq10x4jj+6CMjYtZyx9jdMWeV+yFE+ItFcO1NeUAEWd2iHC5YPD0P2tHiHx5kscsw=="
|
||||||
},
|
},
|
||||||
"cordova-plugin-screen-orientation": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/cordova-plugin-screen-orientation/-/cordova-plugin-screen-orientation-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-2w6CMC+HGvbhogJetalwGurL2Fx8DQCCPy3wlSZHN1/W7WoQ5n9ujVozcoKrY4VaagK6bxrPFih+ElkO8Uqfzg=="
|
|
||||||
},
|
|
||||||
"cordova-plugin-splashscreen": {
|
"cordova-plugin-splashscreen": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cordova-plugin-splashscreen/-/cordova-plugin-splashscreen-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cordova-plugin-splashscreen/-/cordova-plugin-splashscreen-6.0.0.tgz",
|
||||||
|
@ -41147,6 +41131,7 @@
|
||||||
"version": "0.1.13",
|
"version": "0.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
||||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
||||||
|
"devOptional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"iconv-lite": "^0.6.2"
|
"iconv-lite": "^0.6.2"
|
||||||
},
|
},
|
||||||
|
@ -41155,6 +41140,7 @@
|
||||||
"version": "0.6.2",
|
"version": "0.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
|
||||||
"integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
|
"integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
|
||||||
|
"devOptional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,6 @@
|
||||||
"cordova-plugin-media-capture": "^3.0.3",
|
"cordova-plugin-media-capture": "^3.0.3",
|
||||||
"cordova-plugin-network-information": "^2.0.2",
|
"cordova-plugin-network-information": "^2.0.2",
|
||||||
"cordova-plugin-prevent-override": "^1.0.0",
|
"cordova-plugin-prevent-override": "^1.0.0",
|
||||||
"cordova-plugin-screen-orientation": "^3.0.2",
|
|
||||||
"cordova-plugin-splashscreen": "^6.0.0",
|
"cordova-plugin-splashscreen": "^6.0.0",
|
||||||
"cordova-plugin-statusbar": "^2.4.3",
|
"cordova-plugin-statusbar": "^2.4.3",
|
||||||
"cordova-plugin-whitelist": "^1.3.4",
|
"cordova-plugin-whitelist": "^1.3.4",
|
||||||
|
@ -217,7 +216,6 @@
|
||||||
},
|
},
|
||||||
"cordova-plugin-network-information": {},
|
"cordova-plugin-network-information": {},
|
||||||
"@moodlehq/cordova-plugin-qrscanner": {},
|
"@moodlehq/cordova-plugin-qrscanner": {},
|
||||||
"cordova-plugin-screen-orientation": {},
|
|
||||||
"cordova-plugin-splashscreen": {},
|
"cordova-plugin-splashscreen": {},
|
||||||
"cordova-plugin-statusbar": {},
|
"cordova-plugin-statusbar": {},
|
||||||
"cordova-plugin-whitelist": {},
|
"cordova-plugin-whitelist": {},
|
||||||
|
@ -247,4 +245,4 @@
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"keytar": "^7.2.0"
|
"keytar": "^7.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1574,6 +1574,7 @@
|
||||||
"core.dftimedate": "local_moodlemobileapp",
|
"core.dftimedate": "local_moodlemobileapp",
|
||||||
"core.digitalminor": "moodle",
|
"core.digitalminor": "moodle",
|
||||||
"core.digitalminor_desc": "moodle",
|
"core.digitalminor_desc": "moodle",
|
||||||
|
"core.disablefullscreen": "h5p",
|
||||||
"core.discard": "local_moodlemobileapp",
|
"core.discard": "local_moodlemobileapp",
|
||||||
"core.dismiss": "local_moodlemobileapp",
|
"core.dismiss": "local_moodlemobileapp",
|
||||||
"core.displayoptions": "atto_media",
|
"core.displayoptions": "atto_media",
|
||||||
|
@ -1658,6 +1659,7 @@
|
||||||
"core.forcepasswordchangenotice": "moodle",
|
"core.forcepasswordchangenotice": "moodle",
|
||||||
"core.fulllistofcourses": "moodle",
|
"core.fulllistofcourses": "moodle",
|
||||||
"core.fullnameandsitename": "local_moodlemobileapp",
|
"core.fullnameandsitename": "local_moodlemobileapp",
|
||||||
|
"core.fullscreen": "h5p",
|
||||||
"core.grades.aggregatemean": "grades",
|
"core.grades.aggregatemean": "grades",
|
||||||
"core.grades.aggregatesum": "grades",
|
"core.grades.aggregatesum": "grades",
|
||||||
"core.grades.average": "grades",
|
"core.grades.average": "grades",
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<h2>{{ 'addon.block_activitymodules.pluginname' | translate }}</h2>
|
<h2>{{ 'addon.block_activitymodules.pluginname' | translate }}</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin">
|
<core-loading [hideUntil]="loaded" [fullscreen]="false">
|
||||||
<ion-item class="ion-text-wrap item-media" *ngFor="let entry of entries" detail="true" button
|
<ion-item class="ion-text-wrap item-media" *ngFor="let entry of entries" detail="true" button
|
||||||
(click)="gotoCoureListModType(entry)">
|
(click)="gotoCoureListModType(entry)">
|
||||||
<core-mod-icon slot="start" [modicon]="entry.icon" [modname]="entry.modName" [showAlt]="false">
|
<core-mod-icon slot="start" [modicon]="entry.icon" [modname]="entry.modName" [showAlt]="false">
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
</core-context-menu>
|
</core-context-menu>
|
||||||
</div>
|
</div>
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin">
|
<core-loading [hideUntil]="loaded" [fullscreen]="false">
|
||||||
<div class="safe-padding-horizontal" [hidden]="showFilter || !showSelectorFilter">
|
<div class="safe-area-padding-horizontal" [hidden]="showFilter || !showSelectorFilter">
|
||||||
<!-- "Time" selector. -->
|
<!-- "Time" selector. -->
|
||||||
<core-combobox [label]="'core.show' | translate" [selection]="selectedFilter" (onChange)="selectedChanged($event)">
|
<core-combobox [label]="'core.show' | translate" [selection]="selectedFilter" (onChange)="selectedChanged($event)">
|
||||||
<ion-select-option class="ion-text-wrap" value="allincludinghidden" *ngIf="showFilters.allincludinghidden != 'hidden'">
|
<ion-select-option class="ion-text-wrap" value="allincludinghidden" *ngIf="showFilters.allincludinghidden != 'hidden'">
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
</core-empty-box>
|
</core-empty-box>
|
||||||
|
|
||||||
<!-- List of courses. -->
|
<!-- List of courses. -->
|
||||||
<div class="safe-area-page">
|
<div class="safe-area-padding">
|
||||||
<ion-grid class="ion-no-padding">
|
<ion-grid class="ion-no-padding">
|
||||||
<ion-row class="ion-no-padding">
|
<ion-row class="ion-no-padding">
|
||||||
<ion-col *ngFor="let course of filteredCourses" class="ion-no-padding"
|
<ion-col *ngFor="let course of filteredCourses" class="ion-no-padding"
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
</core-horizontal-scroll-controls>
|
</core-horizontal-scroll-controls>
|
||||||
</div>
|
</div>
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page margin">
|
<core-loading [hideUntil]="loaded" [fullscreen]="false">
|
||||||
<core-empty-box *ngIf="courses.length == 0" image="assets/img/icons/courses.svg" inline="true"
|
<core-empty-box *ngIf="courses.length == 0" image="assets/img/icons/courses.svg" inline="true"
|
||||||
[message]="'addon.block_recentlyaccessedcourses.nocourses' | translate"></core-empty-box>
|
[message]="'addon.block_recentlyaccessedcourses.nocourses' | translate"></core-empty-box>
|
||||||
<!-- List of courses. -->
|
<!-- List of courses. -->
|
||||||
|
@ -31,10 +31,12 @@
|
||||||
(scroll)="scrollControls.updateScrollPosition()"
|
(scroll)="scrollControls.updateScrollPosition()"
|
||||||
>
|
>
|
||||||
<div (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
|
<div (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
|
||||||
|
<div class="safe-area-pseudo-padding-start"></div>
|
||||||
<ng-container *ngFor="let course of courses">
|
<ng-container *ngFor="let course of courses">
|
||||||
<core-courses-course-progress [course]="course" class="core-recentlyaccessedcourses"
|
<core-courses-course-progress [course]="course" class="core-recentlyaccessedcourses"
|
||||||
[showDownload]="downloadCourseEnabled && downloadEnabled"></core-courses-course-progress>
|
[showDownload]="downloadCourseEnabled && downloadEnabled"></core-courses-course-progress>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<div class="safe-area-pseudo-padding-end"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</core-horizontal-scroll-controls>
|
</core-horizontal-scroll-controls>
|
||||||
</div>
|
</div>
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" [fullscreen]="false">
|
||||||
<div
|
<div
|
||||||
[id]="scrollElementId"
|
[id]="scrollElementId"
|
||||||
[hidden]="!items || items.length === 0"
|
[hidden]="!items || items.length === 0"
|
||||||
|
@ -13,7 +13,8 @@
|
||||||
(scroll)="scrollControls.updateScrollPosition()"
|
(scroll)="scrollControls.updateScrollPosition()"
|
||||||
>
|
>
|
||||||
<div *ngIf="items" (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
|
<div *ngIf="items" (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
|
||||||
<div *ngFor="let item of items">
|
<div class="safe-area-pseudo-padding-start"></div>
|
||||||
|
<div *ngFor="let item of items" class="core-horizontal-scroll-item">
|
||||||
<ion-card>
|
<ion-card>
|
||||||
<ion-item class="core-course-module-handler item-media ion-text-wrap" detail="false" (click)="action($event, item)"
|
<ion-item class="core-course-module-handler item-media ion-text-wrap" detail="false" (click)="action($event, item)"
|
||||||
button>
|
button>
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-card>
|
</ion-card>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="safe-area-pseudo-padding-end"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
@import "~theme/globals";
|
@import "~theme/globals";
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
.core-horizontal-scroll > div > div {
|
.core-horizontal-scroll div.core-horizontal-scroll-item {
|
||||||
@include horizontal_scroll_item(80%, 250px, 300px);
|
@include horizontal_scroll_item(80%, 250px, 300px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-course-module-handler {
|
.core-course-module-handler {
|
||||||
--inner-border-width: 0;
|
--inner-border-width: 0px;
|
||||||
}
|
}
|
||||||
core-loading {
|
core-loading {
|
||||||
--loading-inline-min-height: 102px;
|
--loading-inline-min-height: 102px;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<h2>{{ 'addon.block_sitemainmenu.pluginname' | translate }}</h2>
|
<h2>{{ 'addon.block_sitemainmenu.pluginname' | translate }}</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin">
|
<core-loading [hideUntil]="loaded" [fullscreen]="false">
|
||||||
<ng-container *ngIf="mainMenuBlock">
|
<ng-container *ngIf="mainMenuBlock">
|
||||||
<ion-item class="ion-text-wrap" *ngIf="mainMenuBlock.summary">
|
<ion-item class="ion-text-wrap" *ngIf="mainMenuBlock.summary">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
</core-horizontal-scroll-controls>
|
</core-horizontal-scroll-controls>
|
||||||
</div>
|
</div>
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page margin">
|
<core-loading [hideUntil]="loaded" [fullscreen]="false">
|
||||||
<core-empty-box *ngIf="courses.length == 0" image="assets/img/icons/courses.svg" inline="true"
|
<core-empty-box *ngIf="courses.length == 0" image="assets/img/icons/courses.svg" inline="true"
|
||||||
[message]="'addon.block_starredcourses.nocourses' | translate"></core-empty-box>
|
[message]="'addon.block_starredcourses.nocourses' | translate"></core-empty-box>
|
||||||
<!-- List of courses. -->
|
<!-- List of courses. -->
|
||||||
|
@ -32,10 +32,12 @@
|
||||||
(scroll)="scrollControls.updateScrollPosition()"
|
(scroll)="scrollControls.updateScrollPosition()"
|
||||||
>
|
>
|
||||||
<div (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
|
<div (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
|
||||||
|
<div class="safe-area-pseudo-padding-start"></div>
|
||||||
<ng-container *ngFor="let course of courses">
|
<ng-container *ngFor="let course of courses">
|
||||||
<core-courses-course-progress [course]="course" class="core-block_starredcourses"
|
<core-courses-course-progress [course]="course" class="core-block_starredcourses"
|
||||||
[showDownload]="downloadCourseEnabled && downloadEnabled"></core-courses-course-progress>
|
[showDownload]="downloadCourseEnabled && downloadEnabled"></core-courses-course-progress>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<div class="safe-area-pseudo-padding-end"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
</core-context-menu>
|
</core-context-menu>
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin">
|
<core-loading [hideUntil]="loaded" [fullscreen]="false">
|
||||||
<div class="safe-padding-horizontal">
|
<div class="safe-area-padding-horizontal">
|
||||||
<core-combobox [selection]="filter" (onChange)="switchFilter($event)">
|
<core-combobox [selection]="filter" (onChange)="switchFilter($event)">
|
||||||
<ion-select-option class="ion-text-wrap" value="all">
|
<ion-select-option class="ion-text-wrap" value="all">
|
||||||
{{ 'core.all' | translate }}
|
{{ 'core.all' | translate }}
|
||||||
|
@ -35,12 +35,12 @@
|
||||||
</ion-select-option>
|
</ion-select-option>
|
||||||
</core-combobox>
|
</core-combobox>
|
||||||
</div>
|
</div>
|
||||||
<core-loading [hideUntil]="timeline.loaded" [hidden]="sort != 'sortbydates'" [fullscreen]="false" class="margin">
|
<core-loading [hideUntil]="timeline.loaded" [hidden]="sort != 'sortbydates'" [fullscreen]="false">
|
||||||
<addon-block-timeline-events [events]="timeline.events" showCourse="true" [canLoadMore]="timeline.canLoadMore"
|
<addon-block-timeline-events [events]="timeline.events" showCourse="true" [canLoadMore]="timeline.canLoadMore"
|
||||||
(loadMore)="loadMoreTimeline()" [from]="dataFrom" [to]="dataTo"></addon-block-timeline-events>
|
(loadMore)="loadMoreTimeline()" [from]="dataFrom" [to]="dataTo"></addon-block-timeline-events>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
<core-loading [hideUntil]="timelineCourses.loaded" [hidden]="sort != 'sortbycourses'"
|
<core-loading [hideUntil]="timelineCourses.loaded" [hidden]="sort != 'sortbycourses'"
|
||||||
[fullscreen]="false" class="safe-area-page margin">
|
[fullscreen]="false" class="safe-area-padding">
|
||||||
<ion-grid class="ion-no-padding">
|
<ion-grid class="ion-no-padding">
|
||||||
<ion-row class="ion-no-padding">
|
<ion-row class="ion-no-padding">
|
||||||
<ion-col *ngFor="let course of timelineCourses.courses" class="ion-no-padding" size="12" size-md="6">
|
<ion-col *ngFor="let course of timelineCourses.courses" class="ion-no-padding" size="12" size-md="6">
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</core-context-menu>
|
</core-context-menu>
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
<!-- Period name and arrows to navigate. -->
|
<!-- Period name and arrows to navigate. -->
|
||||||
<ion-grid class="ion-no-padding addon-calendar-navigation">
|
<ion-grid class="ion-no-padding addon-calendar-navigation">
|
||||||
<ion-row class="ion-align-items-center">
|
<ion-row class="ion-align-items-center">
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
|
|
||||||
<!-- Period name and arrows to navigate. -->
|
<!-- Period name and arrows to navigate. -->
|
||||||
<ion-grid class="ion-no-padding safe-area-page">
|
<ion-grid class="ion-no-padding safe-area-padding">
|
||||||
<ion-row class="ion-align-items-center">
|
<ion-row class="ion-align-items-center">
|
||||||
<ion-col class="ion-text-start" *ngIf="currentMoment">
|
<ion-col class="ion-text-start" *ngIf="currentMoment">
|
||||||
<ion-button fill="clear" (click)="loadPrevious()" [attr.aria-label]="'addon.calendar.dayprev' | translate">
|
<ion-button fill="clear" (click)="loadPrevious()" [attr.aria-label]="'addon.calendar.dayprev' | translate">
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
</ion-row>
|
</ion-row>
|
||||||
</ion-grid>
|
</ion-grid>
|
||||||
|
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
<!-- There is data to be synchronized -->
|
<!-- There is data to be synchronized -->
|
||||||
<ion-card class="core-warning-card" *ngIf="hasOffline">
|
<ion-card class="core-warning-card" *ngIf="hasOffline">
|
||||||
<ion-item>
|
<ion-item>
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content class="has-footer" (ionScroll)="scrollFunction()">
|
<ion-content class="has-footer" (ionScroll)="scrollFunction()">
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding-horizontal">
|
||||||
<!-- Load previous messages. -->
|
<!-- Load previous messages. -->
|
||||||
<core-infinite-loading [enabled]="canLoadMore" (action)="loadPrevious($event)" position="top" [error]="loadMoreError">
|
<core-infinite-loading [enabled]="canLoadMore" (action)="loadPrevious($event)" position="top" [error]="loadMoreError">
|
||||||
</core-infinite-loading>
|
</core-infinite-loading>
|
||||||
|
@ -138,8 +138,8 @@
|
||||||
</ion-fab-button>
|
</ion-fab-button>
|
||||||
</ion-fab>
|
</ion-fab>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
<ion-footer color="light" class="footer-adjustable" *ngIf="loaded && (!conversationId || conversation)">
|
<ion-footer class="footer-adjustable" *ngIf="loaded && (!conversationId || conversation)">
|
||||||
<ion-toolbar color="light">
|
<ion-toolbar [color]="footerType == 'message' ? 'contrast' : 'light'">
|
||||||
<p *ngIf="footerType == 'unable'" class="ion-text-center ion-margin-horizontal">
|
<p *ngIf="footerType == 'unable'" class="ion-text-center ion-margin-horizontal">
|
||||||
{{ 'addon.messages.unabletomessage' | translate }}
|
{{ 'addon.messages.unabletomessage' | translate }}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<core-loading [hideUntil]="loaded" class="margin">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- User and status of the submission. -->
|
<!-- User and status of the submission. -->
|
||||||
<ion-item class="ion-text-wrap" *ngIf="!blindMarking && user" core-user-link [userId]="submitId" [courseId]="courseId"
|
<ion-item class="ion-text-wrap" *ngIf="!blindMarking && user" core-user-link [userId]="submitId" [courseId]="courseId"
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-card>
|
</ion-card>
|
||||||
|
|
||||||
<div class="ion-padding safe-padding-horizontal">
|
<div class="ion-padding safe-area-padding-horizontal">
|
||||||
<core-navigation-bar *ngIf="displayNavBar" [previous]="previousChapter?.id"
|
<core-navigation-bar *ngIf="displayNavBar" [previous]="previousChapter?.id"
|
||||||
[previousTitle]="previousNavBarTitle" [next]="nextChapter?.id" [nextTitle]="nextNavBarTitle"
|
[previousTitle]="previousNavBarTitle" [next]="nextChapter?.id" [nextTitle]="nextNavBarTitle"
|
||||||
(action)="changeChapter($event)">
|
(action)="changeChapter($event)">
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<!-- Content. -->
|
<!-- Content. -->
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content class="has-footer">
|
<ion-content class="has-footer">
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
<ion-list class="addon-messages-discussion-container" aria-live="polite">
|
<ion-list class="addon-messages-discussion-container" aria-live="polite">
|
||||||
<ng-container *ngFor="let message of messages; index as index; last as last">
|
<ng-container *ngFor="let message of messages; index as index; last as last">
|
||||||
|
|
||||||
|
@ -109,8 +109,8 @@
|
||||||
</core-empty-box>
|
</core-empty-box>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
<ion-footer color="light" class="footer-adjustable">
|
<ion-footer class="footer-adjustable">
|
||||||
<ion-toolbar color="light">
|
<ion-toolbar [color]="isOnline && polling && loaded ? 'contrast' : 'light'">
|
||||||
<p class="ion-text-center" *ngIf="!isOnline">
|
<p class="ion-text-center" *ngIf="!isOnline">
|
||||||
{{ 'addon.mod_chat.mustbeonlinetosendmessages' | translate }}
|
{{ 'addon.mod_chat.mustbeonlinetosendmessages' | translate }}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refreshMessages($event.target)">
|
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refreshMessages($event.target)">
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
<ion-list class="addon-messages-discussion-container">
|
<ion-list class="addon-messages-discussion-container">
|
||||||
<ng-container *ngFor="let message of messages; index as index;">
|
<ng-container *ngFor="let message of messages; index as index;">
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
:host {
|
:host {
|
||||||
--input-border-color: var(--gray);
|
--input-border-color: var(--gray);
|
||||||
--input-border-width: 1px;
|
--input-border-width: 1px;
|
||||||
--select-border-width: 0;
|
--select-border-width: 0px;
|
||||||
|
|
||||||
::ng-deep {
|
::ng-deep {
|
||||||
table {
|
table {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin">
|
<core-loading [hideUntil]="loaded" [fullscreen]="false">
|
||||||
<ion-item button class="ion-text-wrap" (click)="editPost()" *ngIf="offlinePost || (canEdit && isOnline)" detail="false">
|
<ion-item button class="ion-text-wrap" (click)="editPost()" *ngIf="offlinePost || (canEdit && isOnline)" detail="false">
|
||||||
<ion-icon name="fas-pen" slot="start" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-pen" slot="start" aria-hidden="true"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<!-- Content. -->
|
<!-- Content. -->
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
.core-warning-item {
|
.core-warning-item {
|
||||||
--inner-border-width: 0;
|
--inner-border-width: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addon-mod_h5pactivity-attempt-result-summary {
|
.addon-mod_h5pactivity-attempt-result-summary {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<!-- Content. -->
|
<!-- Content. -->
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<!-- Content. -->
|
<!-- Content. -->
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<!-- Content. -->
|
<!-- Content. -->
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<!-- Content. -->
|
<!-- Content. -->
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page core-loading-fullheight">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding core-loading-fullheight">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<!-- Content. -->
|
<!-- Content. -->
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
<core-loading [hideUntil]="loaded" class="core-loading-fullheight">
|
<core-loading [hideUntil]="loaded" class="core-loading-fullheight">
|
||||||
<core-navigation-bar [previous]="previousSco" [next]="nextSco" (action)="loadSco($event)"></core-navigation-bar>
|
<core-navigation-bar [previous]="previousSco" [next]="nextSco" (action)="loadSco($event)"></core-navigation-bar>
|
||||||
|
|
||||||
<core-iframe *ngIf="loaded && src" [src]="src" [iframeWidth]="scormWidth" [iframeHeight]="scormHeight"></core-iframe>
|
<core-iframe *ngIf="loaded && src" [src]="src" [iframeWidth]="scormWidth" [iframeHeight]="scormHeight"
|
||||||
|
[showFullscreenOnToolbar]="true" [autoFullscreenOnRotate]="true">
|
||||||
|
</core-iframe>
|
||||||
|
|
||||||
<p *ngIf="!src && errorMessage">{{ errorMessage | translate }}</p>
|
<p *ngIf="!src && errorMessage">{{ errorMessage | translate }}</p>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
|
@ -66,7 +66,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
protected moduleUrl!: string; // Module URL.
|
protected moduleUrl!: string; // Module URL.
|
||||||
protected newAttempt = false; // Whether to start a new attempt.
|
protected newAttempt = false; // Whether to start a new attempt.
|
||||||
protected organizationId?: string; // Organization ID to load.
|
protected organizationId?: string; // Organization ID to load.
|
||||||
protected attempt?: number; // The attempt number.
|
protected attempt = 0; // The attempt number.
|
||||||
protected offline = false; // Whether it's offline mode.
|
protected offline = false; // Whether it's offline mode.
|
||||||
protected userData?: AddonModScormUserDataMap; // User data.
|
protected userData?: AddonModScormUserDataMap; // User data.
|
||||||
protected initialScoId?: number; // Initial SCO ID to load.
|
protected initialScoId?: number; // Initial SCO ID to load.
|
||||||
|
@ -96,7 +96,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
this.newAttempt = !!CoreNavigator.getRouteBooleanParam('newAttempt');
|
this.newAttempt = !!CoreNavigator.getRouteBooleanParam('newAttempt');
|
||||||
this.organizationId = CoreNavigator.getRouteParam('organizationId');
|
this.organizationId = CoreNavigator.getRouteParam('organizationId');
|
||||||
this.initialScoId = CoreNavigator.getRouteNumberParam('scoId');
|
this.initialScoId = CoreNavigator.getRouteNumberParam('scoId');
|
||||||
this.siteId = CoreSites.getCurrentSiteId();
|
this.siteId = CoreSites.getRequiredCurrentSite().getId();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
CoreDomUtils.showErrorModal(error);
|
CoreDomUtils.showErrorModal(error);
|
||||||
|
|
||||||
|
@ -150,14 +150,12 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
this.showToc = AddonModScorm.displayTocInPlayer(this.scorm);
|
this.showToc = AddonModScorm.displayTocInPlayer(this.scorm);
|
||||||
|
|
||||||
if (this.scorm.popup) {
|
if (this.scorm.popup) {
|
||||||
this.mainMenuPage.changeVisibility(false);
|
|
||||||
|
|
||||||
// If we receive a value > 100 we assume it's a fixed pixel size.
|
// If we receive a value > 100 we assume it's a fixed pixel size.
|
||||||
if (this.scorm.width! > 100) {
|
if (this.scorm.width && this.scorm.width > 100) {
|
||||||
this.scormWidth = this.scorm.width;
|
this.scormWidth = this.scorm.width;
|
||||||
|
|
||||||
// Only get fixed size on height if width is also fixed.
|
// Only get fixed size on height if width is also fixed.
|
||||||
if (this.scorm.height! > 100) {
|
if (this.scorm.height && this.scorm.height > 100) {
|
||||||
this.scormHeight = this.scorm.height;
|
this.scormHeight = this.scorm.height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,7 +196,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
// Wait a bit to prevent collisions between this store and SCORM API's store.
|
// Wait a bit to prevent collisions between this store and SCORM API's store.
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
AddonModScormHelper.convertAttemptToOffline(this.scorm, this.attempt!);
|
AddonModScormHelper.convertAttemptToOffline(this.scorm, this.attempt);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
CoreDomUtils.instance.showErrorModalDefault(error, 'core.error', true);
|
CoreDomUtils.instance.showErrorModalDefault(error, 'core.error', true);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +290,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
await this.determineAttemptAndMode(attemptsData);
|
await this.determineAttemptAndMode(attemptsData);
|
||||||
|
|
||||||
const [data, accessInfo] = await Promise.all([
|
const [data, accessInfo] = await Promise.all([
|
||||||
AddonModScorm.getScormUserData(this.scorm.id, this.attempt!, {
|
AddonModScorm.getScormUserData(this.scorm.id, this.attempt, {
|
||||||
cmId: this.cmId,
|
cmId: this.cmId,
|
||||||
offline: this.offline,
|
offline: this.offline,
|
||||||
}),
|
}),
|
||||||
|
@ -319,13 +317,13 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// We need to check incomplete again: attempt number or status might have changed.
|
// We need to check incomplete again: attempt number or status might have changed.
|
||||||
this.incomplete = await AddonModScorm.isAttemptIncomplete(this.scorm.id, this.attempt!, {
|
this.incomplete = await AddonModScorm.isAttemptIncomplete(this.scorm.id, this.attempt, {
|
||||||
offline: this.offline,
|
offline: this.offline,
|
||||||
cmId: this.cmId,
|
cmId: this.cmId,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get TOC.
|
// Get TOC.
|
||||||
this.toc = await AddonModScormHelper.getToc(this.scorm.id, this.attempt!, this.incomplete, {
|
this.toc = await AddonModScormHelper.getToc(this.scorm.id, this.attempt, this.incomplete, {
|
||||||
organization: this.organizationId,
|
organization: this.organizationId,
|
||||||
offline: this.offline,
|
offline: this.offline,
|
||||||
cmId: this.cmId,
|
cmId: this.cmId,
|
||||||
|
@ -351,7 +349,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
// No SCO defined. Get the first valid one.
|
// No SCO defined. Get the first valid one.
|
||||||
const sco = await AddonModScormHelper.getFirstSco(this.scorm.id, this.attempt!, {
|
const sco = await AddonModScormHelper.getFirstSco(this.scorm.id, this.attempt, {
|
||||||
toc: this.toc,
|
toc: this.toc,
|
||||||
organization: this.organizationId,
|
organization: this.organizationId,
|
||||||
mode: this.mode,
|
mode: this.mode,
|
||||||
|
@ -383,7 +381,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
this.siteId,
|
this.siteId,
|
||||||
this.scorm,
|
this.scorm,
|
||||||
sco.id,
|
sco.id,
|
||||||
this.attempt!,
|
this.attempt,
|
||||||
this.userData!,
|
this.userData!,
|
||||||
this.mode,
|
this.mode,
|
||||||
this.offline,
|
this.offline,
|
||||||
|
@ -446,14 +444,14 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
}];
|
}];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
AddonModScorm.saveTracks(sco.id, this.attempt!, tracks, this.scorm, this.offline);
|
AddonModScorm.saveTracks(sco.id, this.attempt, tracks, this.scorm, this.offline);
|
||||||
} catch {
|
} catch {
|
||||||
// Error saving data. Go offline if needed.
|
// Error saving data. Go offline if needed.
|
||||||
if (this.offline) {
|
if (this.offline) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await AddonModScorm.getScormUserData(this.scorm.id, this.attempt!, {
|
const data = await AddonModScorm.getScormUserData(this.scorm.id, this.attempt, {
|
||||||
cmId: this.cmId,
|
cmId: this.cmId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -464,12 +462,12 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Go offline.
|
// Go offline.
|
||||||
await AddonModScormHelper.convertAttemptToOffline(this.scorm, this.attempt!);
|
await AddonModScormHelper.convertAttemptToOffline(this.scorm, this.attempt);
|
||||||
|
|
||||||
this.offline = true;
|
this.offline = true;
|
||||||
this.dataModel?.setOffline(true);
|
this.dataModel?.setOffline(true);
|
||||||
|
|
||||||
await AddonModScorm.saveTracks(sco.id, this.attempt!, tracks, this.scorm, true);
|
await AddonModScorm.saveTracks(sco.id, this.attempt, tracks, this.scorm, true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
CoreDomUtils.instance.showErrorModalDefault(error, 'core.error', true);
|
CoreDomUtils.instance.showErrorModalDefault(error, 'core.error', true);
|
||||||
}
|
}
|
||||||
|
@ -528,7 +526,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
value: String(CoreTimeUtils.timestamp()),
|
value: String(CoreTimeUtils.timestamp()),
|
||||||
}];
|
}];
|
||||||
|
|
||||||
await AddonModScorm.saveTracks(scoId, this.attempt!, tracks, this.scorm, this.offline);
|
await AddonModScorm.saveTracks(scoId, this.attempt, tracks, this.scorm, this.offline);
|
||||||
|
|
||||||
if (this.offline) {
|
if (this.offline) {
|
||||||
return;
|
return;
|
||||||
|
@ -541,22 +539,6 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
ionViewDidEnter(): void {
|
|
||||||
if (this.scorm && this.scorm.popup) {
|
|
||||||
this.mainMenuPage.changeVisibility(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
ionViewWillLeave(): void {
|
|
||||||
this.mainMenuPage.changeVisibility(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component being destroyed.
|
* Component being destroyed.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<!-- Content. -->
|
<!-- Content. -->
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
||||||
|
|
|
@ -63,7 +63,6 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
* - IAB events listening.
|
* - IAB events listening.
|
||||||
* - Platform pause/resume subscriptions.
|
* - Platform pause/resume subscriptions.
|
||||||
* - handleOpenURL and openWindowSafely.
|
* - handleOpenURL and openWindowSafely.
|
||||||
* - Screen orientation events (probably it can be removed).
|
|
||||||
* - Back button registering to close modal first.
|
* - Back button registering to close modal first.
|
||||||
* - Note: HideKeyboardFormAccessoryBar has been moved to config.xml.
|
* - Note: HideKeyboardFormAccessoryBar has been moved to config.xml.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
@include margin-horizontal(var(--ion-safe-area-left), var(--ion-safe-area-right));
|
||||||
|
|
||||||
ion-select,
|
ion-select,
|
||||||
ion-button {
|
ion-button {
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
<div [class.core-loading-container]="loading || !safeUrl" [ngStyle]="{'width': iframeWidth, 'height': iframeHeight}">
|
<div [class.core-loading-container]="loading || !safeUrl" [ngStyle]="{'width': iframeWidth, 'height': iframeHeight}">
|
||||||
|
|
||||||
|
<core-navbar-buttons slot="end" append *ngIf="initialized && showFullscreenOnToolbar">
|
||||||
|
<ion-button fill="clear" (click)="toggleFullscreen()"
|
||||||
|
[attr.aria-label]="(fullscreen ? 'core.disablefullscreen' : 'core.fullscreen') | translate" >
|
||||||
|
<ion-icon *ngIf="!fullscreen" name="fas-expand" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
|
<ion-icon *ngIf="fullscreen" name="fas-compress" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
|
</ion-button>
|
||||||
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<!-- Don't add the iframe until safeUrl is set, adding an iframe with null as src causes the iframe to load the whole app. -->
|
<!-- Don't add the iframe until safeUrl is set, adding an iframe with null as src causes the iframe to load the whole app. -->
|
||||||
<iframe #iframe *ngIf="safeUrl" [hidden]="loading" class="core-iframe"
|
<iframe #iframe *ngIf="safeUrl" [hidden]="loading" class="core-iframe"
|
||||||
[ngStyle]="{'width': iframeWidth, 'height': iframeHeight}" [src]="safeUrl"
|
[ngStyle]="{'width': iframeWidth, 'height': iframeHeight}" [src]="safeUrl"
|
||||||
|
|
|
@ -30,3 +30,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:host-context(.core-iframe-fullscreen) {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Component, Input, Output, ViewChild, ElementRef, EventEmitter, OnChanges, SimpleChange,
|
Component, Input, Output, ViewChild, ElementRef, EventEmitter, OnChanges, SimpleChange, OnDestroy,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { SafeResourceUrl } from '@angular/platform-browser';
|
import { SafeResourceUrl } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
@ -22,15 +22,16 @@ import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreUrlUtils } from '@services/utils/url';
|
import { CoreUrlUtils } from '@services/utils/url';
|
||||||
import { CoreIframeUtils } from '@services/utils/iframe';
|
import { CoreIframeUtils } from '@services/utils/iframe';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { DomSanitizer, StatusBar } from '@singletons';
|
||||||
import { DomSanitizer } from '@singletons';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
|
import { CoreScreen, CoreScreenOrientation } from '@services/screen';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'core-iframe',
|
selector: 'core-iframe',
|
||||||
templateUrl: 'core-iframe.html',
|
templateUrl: 'core-iframe.html',
|
||||||
styleUrls: ['iframe.scss'],
|
styleUrls: ['iframe.scss'],
|
||||||
})
|
})
|
||||||
export class CoreIframeComponent implements OnChanges {
|
export class CoreIframeComponent implements OnChanges, OnDestroy {
|
||||||
|
|
||||||
static loadingTimeout = 15000;
|
static loadingTimeout = 15000;
|
||||||
|
|
||||||
|
@ -39,17 +40,21 @@ export class CoreIframeComponent implements OnChanges {
|
||||||
@Input() iframeWidth?: string;
|
@Input() iframeWidth?: string;
|
||||||
@Input() iframeHeight?: string;
|
@Input() iframeHeight?: string;
|
||||||
@Input() allowFullscreen?: boolean | string;
|
@Input() allowFullscreen?: boolean | string;
|
||||||
|
@Input() showFullscreenOnToolbar?: boolean | string;
|
||||||
|
@Input() autoFullscreenOnRotate?: boolean | string;
|
||||||
@Output() loaded: EventEmitter<HTMLIFrameElement> = new EventEmitter<HTMLIFrameElement>();
|
@Output() loaded: EventEmitter<HTMLIFrameElement> = new EventEmitter<HTMLIFrameElement>();
|
||||||
|
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
safeUrl?: SafeResourceUrl;
|
safeUrl?: SafeResourceUrl;
|
||||||
displayHelp = false;
|
displayHelp = false;
|
||||||
|
fullscreen = false;
|
||||||
|
|
||||||
protected logger: CoreLogger;
|
initialized = false;
|
||||||
protected initialized = false;
|
|
||||||
|
protected style?: HTMLStyleElement;
|
||||||
|
protected orientationObs?: CoreEventObserver;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.logger = CoreLogger.getInstance('CoreIframe');
|
|
||||||
this.loaded = new EventEmitter<HTMLIFrameElement>();
|
this.loaded = new EventEmitter<HTMLIFrameElement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +76,25 @@ export class CoreIframeComponent implements OnChanges {
|
||||||
this.iframeWidth = (this.iframeWidth && CoreDomUtils.formatPixelsSize(this.iframeWidth)) || '100%';
|
this.iframeWidth = (this.iframeWidth && CoreDomUtils.formatPixelsSize(this.iframeWidth)) || '100%';
|
||||||
this.iframeHeight = (this.iframeHeight && CoreDomUtils.formatPixelsSize(this.iframeHeight)) || '100%';
|
this.iframeHeight = (this.iframeHeight && CoreDomUtils.formatPixelsSize(this.iframeHeight)) || '100%';
|
||||||
this.allowFullscreen = CoreUtils.isTrueOrOne(this.allowFullscreen);
|
this.allowFullscreen = CoreUtils.isTrueOrOne(this.allowFullscreen);
|
||||||
|
this.showFullscreenOnToolbar = CoreUtils.isTrueOrOne(this.showFullscreenOnToolbar);
|
||||||
|
this.autoFullscreenOnRotate = CoreUtils.isTrueOrOne(this.autoFullscreenOnRotate);
|
||||||
|
|
||||||
|
if (this.showFullscreenOnToolbar || this.autoFullscreenOnRotate) {
|
||||||
|
const shadow =
|
||||||
|
iframe.closest('.ion-page')?.querySelector('ion-header ion-toolbar')?.shadowRoot;
|
||||||
|
if (shadow) {
|
||||||
|
this.style = document.createElement('style');
|
||||||
|
shadow.appendChild(this.style);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.autoFullscreenOnRotate) {
|
||||||
|
this.toggleFullscreen(CoreScreen.isLandscape);
|
||||||
|
|
||||||
|
this.orientationObs = CoreEvents.on(CoreEvents.ORIENTATION_CHANGE, (data) => {
|
||||||
|
this.toggleFullscreen(data.orientation == CoreScreenOrientation.LANDSCAPE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Show loading only with external URLs.
|
// Show loading only with external URLs.
|
||||||
this.loading = !this.src || !CoreUrlUtils.isLocalFileUrl(this.src);
|
this.loading = !this.src || !CoreUrlUtils.isLocalFileUrl(this.src);
|
||||||
|
@ -120,4 +144,35 @@ export class CoreIframeComponent implements OnChanges {
|
||||||
CoreIframeUtils.openIframeHelpModal();
|
CoreIframeUtils.openIframeHelpModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.toggleFullscreen(false);
|
||||||
|
this.orientationObs?.off();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle fullscreen mode.
|
||||||
|
*/
|
||||||
|
toggleFullscreen(enable?: boolean): void {
|
||||||
|
if (enable !== undefined) {
|
||||||
|
this.fullscreen = enable;
|
||||||
|
} else {
|
||||||
|
this.fullscreen = !this.fullscreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fullscreen ? StatusBar.hide() : StatusBar.show();
|
||||||
|
|
||||||
|
if (this.style) {
|
||||||
|
// Done this way because of the shadow DOM.
|
||||||
|
this.style.textContent = this.fullscreen
|
||||||
|
? '@media screen and (orientation: landscape) {\
|
||||||
|
.toolbar-container { flex-direction: column-reverse !important; height: 100%; } }'
|
||||||
|
: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.classList.toggle('core-iframe-fullscreen', this.fullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
--loading-background-inline: var(--ion-background-color-rgb);
|
--loading-background-inline: var(--ion-background-color-rgb);
|
||||||
--loading-spinner: var(--ion-color-primary);
|
--loading-spinner: var(--ion-color-primary);
|
||||||
--loading-text-color: var(--ion-text-color);
|
--loading-text-color: var(--ion-text-color);
|
||||||
--loading-inline-margin: 0;
|
--loading-inline-margin: 0px;
|
||||||
--loading-inline-min-height: 28px;
|
--loading-inline-min-height: 28px;
|
||||||
--internal-loading-inline-min-height: var(--loading-inline-min-height);
|
--internal-loading-inline-min-height: var(--loading-inline-min-height);
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.core-loading-loaded {
|
&.core-loading-loaded {
|
||||||
--internal-loading-inline-min-height: 0;
|
--internal-loading-inline-min-height: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-spinner {
|
ion-spinner {
|
||||||
|
@ -74,6 +74,18 @@
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.safe-area-padding:not(.core-loading-inline) .core-loading-content,
|
||||||
|
&.safe-area-padding-horizontal:not(.core-loading-inline) .core-loading-content {
|
||||||
|
@include safe-area-padding-horizontal(0px, 0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.safe-area-padding:not(.core-loading-inline) .core-loading-content {
|
||||||
|
padding-bottom: var(--ion-safe-area-bottom);
|
||||||
|
> * {
|
||||||
|
--ion-safe-area-bottom: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:host-context(ion-item) {
|
:host-context(ion-item) {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import "~theme/globals";
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
display: contents;
|
display: contents;
|
||||||
|
|
||||||
|
@ -5,7 +7,7 @@
|
||||||
background: transparent;
|
background: transparent;
|
||||||
padding: 0 calc(var(--padding-start) / 2);
|
padding: 0 calc(var(--padding-start) / 2);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
@include safe-area-position(null, 0px, null, null);
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
@ -16,11 +18,6 @@
|
||||||
--padding-end: 47px !important;
|
--padding-end: 47px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host-context([dir="rtl"]) ion-button {
|
|
||||||
left: 0;
|
|
||||||
right: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(.md.item-label.stacked) ion-button {
|
:host-context(.md.item-label.stacked) ion-button {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,18 +64,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.menu-only) {
|
:host(.menu-only) {
|
||||||
--menu-min-width: 0;
|
--menu-min-width: 0px;
|
||||||
--menu-max-width: 100%;
|
--menu-max-width: 100%;
|
||||||
--content-display: none;
|
--content-display: none;
|
||||||
--menu-border-width: 0;
|
--menu-border-width: 0px;
|
||||||
--menu-box-shadow: none;
|
--menu-box-shadow: none;
|
||||||
--menu-z: 0;
|
--menu-z: 0px;
|
||||||
--selected-item-color: transparent;
|
--selected-item-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.content-only) {
|
:host(.content-only) {
|
||||||
--menu-display: none;
|
--menu-display: none;
|
||||||
--menu-border-width: 0;
|
--menu-border-width: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.outlet-activated) {
|
:host(.outlet-activated) {
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
ion-tab-bar.core-tabs-bar {
|
ion-tab-bar.core-tabs-bar {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
|
||||||
background: var(--tabs-background);
|
background: var(--tabs-background);
|
||||||
|
@include safe-area-padding-end(null, 0px);
|
||||||
height: var(--height);
|
height: var(--height);
|
||||||
color: var(--tabs-color);
|
color: var(--tabs-color);
|
||||||
-webkit-filter: drop-shadow(0px 3px 3px rgba(var(--drop-shadow)));
|
-webkit-filter: drop-shadow(0px 3px 3px rgba(var(--drop-shadow)));
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="blocks && blocks.length > 0 && !hideBlocks" [class.core-hide-blocks]="hideBottomBlocks" class="core-course-blocks-side">
|
<div *ngIf="blocks && blocks.length > 0 && !hideBlocks" [class.core-hide-blocks]="hideBottomBlocks" class="core-course-blocks-side">
|
||||||
<core-loading [hideUntil]="dataLoaded" [fullscreen]="false" class="margin">
|
<core-loading [hideUntil]="dataLoaded" [fullscreen]="false">
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<!-- Course expand="block"s. -->
|
<!-- Course expand="block"s. -->
|
||||||
<ng-container *ngFor="let block of blocks">
|
<ng-container *ngFor="let block of blocks">
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
|
--ion-safe-area-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.core-course-blocks-side {
|
div.core-course-blocks-side {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
</h2>
|
</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item-divider>
|
</ion-item-divider>
|
||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin">
|
<core-loading [hideUntil]="loaded" [fullscreen]="false">
|
||||||
<ion-item *ngIf="block.contents?.content" class="ion-text-wrap core-block-content">
|
<ion-item *ngIf="block.contents?.content" class="ion-text-wrap core-block-content">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<core-format-text [text]="block.contents?.content" contextLevel="block" [contextInstanceId]="block.instanceid"
|
<core-format-text [text]="block.contents?.content" contextLevel="block" [contextInstanceId]="block.instanceid"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<ng-container *ngIf="!disabled">
|
<ng-container *ngIf="!disabled">
|
||||||
<core-loading *ngIf="!showItem" [hideUntil]="commentsLoaded" [fullscreen]="false" class="margin">
|
<core-loading *ngIf="!showItem" [hideUntil]="commentsLoaded" [fullscreen]="false">
|
||||||
<button *ngIf="!countError" (click)="openComments($event)" class="as-link">
|
<button *ngIf="!countError" (click)="openComments($event)" class="as-link">
|
||||||
{{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }}
|
{{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -119,8 +119,8 @@
|
||||||
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
<ion-footer color="light" class="footer-adjustable" *ngIf="commentsLoaded && canAddComments">
|
<ion-footer class="footer-adjustable" *ngIf="commentsLoaded && canAddComments">
|
||||||
<ion-toolbar color="light">
|
<ion-toolbar color="contrast">
|
||||||
<core-send-message-form [sendDisabled]="sending" [message]="newComment"
|
<core-send-message-form [sendDisabled]="sending" [message]="newComment"
|
||||||
(onSubmit)="addComment($event)" [placeholder]="'core.comments.addcomment' | translate">
|
(onSubmit)="addComment($event)" [placeholder]="'core.comments.addcomment' | translate">
|
||||||
</core-send-message-form>
|
</core-send-message-form>
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
<core-infinite-loading [enabled]="canLoadMore" (action)="showMoreActivities($event)"></core-infinite-loading>
|
<core-infinite-loading [enabled]="canLoadMore" (action)="showMoreActivities($event)"></core-infinite-loading>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ion-buttons class="ion-padding core-course-section-nav-buttons safe-padding-horizontal"
|
<ion-buttons class="ion-padding core-course-section-nav-buttons safe-area-padding-horizontal"
|
||||||
*ngIf="displaySectionSelector && sections?.length">
|
*ngIf="displaySectionSelector && sections?.length">
|
||||||
<ion-button *ngIf="previousSection" (click)="sectionChanged(previousSection)" fill="outline" color="primary"
|
<ion-button *ngIf="previousSection" (click)="sectionChanged(previousSection)" fill="outline" color="primary"
|
||||||
[attr.aria-label]="('core.previous' | translate) + ': ' + previousSection.name">
|
[attr.aria-label]="('core.previous' | translate) + ': ' + previousSection.name">
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-button {
|
ion-button {
|
||||||
--padding-top: 0;
|
--padding-top: 0px;
|
||||||
--padding-start: 0;
|
--padding-start: 0px;
|
||||||
--padding-end: 0;
|
--padding-end: 0px;
|
||||||
--padding-bottom: 0;
|
--padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
@import '~theme/globals.scss';
|
||||||
|
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
@include padding-horizontal(var(--ion-safe-area-left), var(--ion-safe-area-right));
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import { CoreCourseModule, CoreCourseModuleCompletionData } from '@features/cour
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'core-course-module-info',
|
selector: 'core-course-module-info',
|
||||||
templateUrl: 'core-course-module-info.html',
|
templateUrl: 'core-course-module-info.html',
|
||||||
|
styleUrls: ['course-module-info.scss'],
|
||||||
})
|
})
|
||||||
export class CoreCourseModuleInfoComponent {
|
export class CoreCourseModuleInfoComponent {
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-module-main-item.has-module-info {
|
.core-module-main-item.has-module-info {
|
||||||
--inner-border-width: 0;
|
--inner-border-width: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-module-module-info ion-label {
|
.core-module-module-info ion-label {
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<ion-searchbar #searchbar *ngIf="courses && courses.length > 5" [(ngModel)]="filter" (ionInput)="filterChanged($event)"
|
<ion-searchbar #searchbar *ngIf="courses && courses.length > 5" [(ngModel)]="filter" (ionInput)="filterChanged($event)"
|
||||||
(ionCancel)="filterChanged()" [placeholder]="'core.courses.filtermycourses' | translate">
|
(ionCancel)="filterChanged()" [placeholder]="'core.courses.filtermycourses' | translate">
|
||||||
</ion-searchbar>
|
</ion-searchbar>
|
||||||
<ion-grid class="ion-no-padding safe-area-page">
|
<ion-grid class="ion-no-padding safe-area-padding">
|
||||||
<ion-row class="ion-no-padding">
|
<ion-row class="ion-no-padding">
|
||||||
<ion-col *ngFor="let course of filteredCourses" class="ion-no-padding"
|
<ion-col *ngFor="let course of filteredCourses" class="ion-no-padding"
|
||||||
size="12" size-sm="6" size-md="6" size-lg="4" size-xl="4">
|
size="12" size-sm="6" size-md="6" size-lg="4" size-xl="4">
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<ion-refresher slot="fixed" [disabled]="!grades.loaded" (ionRefresh)="refreshGrades($event.target)">
|
<ion-refresher slot="fixed" [disabled]="!grades.loaded" (ionRefresh)="refreshGrades($event.target)">
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-loading [hideUntil]="grades.loaded" class="safe-area-page">
|
<core-loading [hideUntil]="grades.loaded" class="safe-area-padding">
|
||||||
<core-empty-box *ngIf="grades.empty" icon="fas-chart-bar" [message]="'core.grades.nogradesreturned' | translate">
|
<core-empty-box *ngIf="grades.empty" icon="fas-chart-bar" [message]="'core.grades.nogradesreturned' | translate">
|
||||||
</core-empty-box>
|
</core-empty-box>
|
||||||
<div *ngIf="!grades.empty" class="core-grades-container">
|
<div *ngIf="!grades.empty" class="core-grades-container">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<core-loading [hideUntil]="iframeSrc" [fullscreen]="false" class="safe-area-page">
|
<core-loading [hideUntil]="iframeSrc" [fullscreen]="false" class="safe-area-padding">
|
||||||
<core-iframe *ngIf="iframeSrc" [src]="iframeSrc" iframeHeight="auto" [allowFullscreen]="true" (loaded)="iframeLoaded()">
|
<core-iframe *ngIf="iframeSrc" [src]="iframeSrc" iframeHeight="auto" [allowFullscreen]="true" (loaded)="iframeLoaded()">
|
||||||
</core-iframe>
|
</core-iframe>
|
||||||
<script *ngIf="resizeScript && iframeSrc" type="text/javascript" [src]="resizeScript"></script>
|
<script *ngIf="resizeScript && iframeSrc" type="text/javascript" [src]="resizeScript"></script>
|
||||||
|
|
|
@ -51,12 +51,14 @@
|
||||||
ion-tab-bar {
|
ion-tab-bar {
|
||||||
order: -1;
|
order: -1;
|
||||||
width: var(--menutabbar-size);
|
width: var(--menutabbar-size);
|
||||||
height: 100%;
|
height: calc(100% - var(--ion-safe-area-top) - var(--ion-safe-area-bottom));
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@include border-end(var(--border));
|
@include border-end(var(--border));
|
||||||
box-shadow: 3px 0 3px rgba(var(--drop-shadow));
|
box-shadow: 3px 0 3px rgba(var(--drop-shadow));
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
|
|
||||||
|
@include padding(var(--ion-safe-area-top), 0px, var(--ion-safe-area-bottom), var(--ion-safe-area-left));
|
||||||
|
|
||||||
ion-tab-button {
|
ion-tab-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
@ -68,6 +70,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-network-message {
|
.core-network-message {
|
||||||
|
--network-message-height: 16px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -80,6 +83,7 @@
|
||||||
height: 0;
|
height: 0;
|
||||||
transition: all 500ms ease-in-out;
|
transition: all 500ms ease-in-out;
|
||||||
opacity: .8;
|
opacity: .8;
|
||||||
|
z-index: 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-online-message,
|
.core-online-message,
|
||||||
|
@ -100,7 +104,8 @@
|
||||||
|
|
||||||
.core-network-message {
|
.core-network-message {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
height: 16px;
|
height: var(--network-message-height);
|
||||||
|
padding-bottom: calc(var(--ion-safe-area-bottom, 0px) + var(--network-message-height));
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-input {
|
ion-input {
|
||||||
--padding-start: 0;
|
--padding-start: 0px;
|
||||||
--padding-end: 0;
|
--padding-end: 0px;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,8 +388,8 @@ export class CoreSettingsHelperProvider {
|
||||||
*/
|
*/
|
||||||
applyZoomLevel(zoomLevel: CoreZoomLevel): void {
|
applyZoomLevel(zoomLevel: CoreZoomLevel): void {
|
||||||
const zoom = CoreConstants.CONFIG.zoomlevels[zoomLevel];
|
const zoom = CoreConstants.CONFIG.zoomlevels[zoomLevel];
|
||||||
// @todo MOBILE-3790 non-standard property, doesn't work everywhere.
|
|
||||||
document.documentElement.style.zoom = zoom + '%';
|
document.documentElement.style.setProperty('--zoom-level', zoom + '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<core-loading [hideUntil]="dataLoaded" [fullscreen]="false" class="margin">
|
<core-loading [hideUntil]="dataLoaded" [fullscreen]="false">
|
||||||
<core-compile-html [text]="content" [javascript]="javascript" [jsData]="jsData" [forceCompile]="forceCompile" #compile>
|
<core-compile-html [text]="content" [javascript]="javascript" [jsData]="jsData" [forceCompile]="forceCompile" #compile>
|
||||||
</core-compile-html>
|
</core-compile-html>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refreshData($event.target)">
|
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refreshData($event.target)">
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<ion-grid class="safe-area-page">
|
<ion-grid class="safe-area-padding">
|
||||||
<ion-row>
|
<ion-row>
|
||||||
<ion-col size="12" [attr.col-sm-6]="collections && collections.length > 1 ? '' : null">
|
<ion-col size="12" [attr.col-sm-6]="collections && collections.length > 1 ? '' : null">
|
||||||
<core-search-box (onSubmit)="searchTags($event)" (onClear)="searchTags('')" [initialSearch]="query"
|
<core-search-box (onSubmit)="searchTags($event)" (onClear)="searchTags('')" [initialSearch]="query"
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
</ion-grid>
|
</ion-grid>
|
||||||
<core-loading [hideUntil]="loaded && !searching" class="safe-area-page">
|
<core-loading [hideUntil]="loaded && !searching" class="safe-area-padding">
|
||||||
<core-empty-box *ngIf="!cloud || !cloud!.tags || !cloud!.tags.length" icon="fas-tags"
|
<core-empty-box *ngIf="!cloud || !cloud!.tags || !cloud!.tags.length" icon="fas-tags"
|
||||||
[message]="'core.tag.notagsfound' | translate: {$a: query}"></core-empty-box>
|
[message]="'core.tag.notagsfound' | translate: {$a: query}"></core-empty-box>
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="componentId"></core-file>
|
<core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="componentId"></core-file>
|
||||||
</ion-card>
|
</ion-card>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
<ion-footer color="light" *ngIf="displayCopyButton">
|
<ion-footer *ngIf="displayCopyButton">
|
||||||
<ion-button expand="block" color="light" (click)="copyText()">
|
<ion-button expand="block" color="light" (click)="copyText()">
|
||||||
<ion-icon name="fas-copy" aria-hidden="true" slot="start"></ion-icon>
|
<ion-icon name="fas-copy" aria-hidden="true" slot="start"></ion-icon>
|
||||||
{{ 'core.copytoclipboard' | translate }}
|
{{ 'core.copytoclipboard' | translate }}
|
||||||
|
|
|
@ -16,4 +16,6 @@ import { CoreScreen } from '@services/screen';
|
||||||
|
|
||||||
export default function(): void {
|
export default function(): void {
|
||||||
CoreScreen.watchViewport();
|
CoreScreen.watchViewport();
|
||||||
|
|
||||||
|
CoreScreen.watchOrientation();
|
||||||
}
|
}
|
|
@ -82,6 +82,7 @@
|
||||||
"dftimedate": "h[:]mm A",
|
"dftimedate": "h[:]mm A",
|
||||||
"digitalminor": "Digital minor",
|
"digitalminor": "Digital minor",
|
||||||
"digitalminor_desc": "Please ask your parent/guardian to contact:",
|
"digitalminor_desc": "Please ask your parent/guardian to contact:",
|
||||||
|
"disablefullscreen": "Disable fullscreen",
|
||||||
"discard": "Discard",
|
"discard": "Discard",
|
||||||
"dismiss": "Dismiss",
|
"dismiss": "Dismiss",
|
||||||
"displayoptions": "Display options",
|
"displayoptions": "Display options",
|
||||||
|
@ -123,6 +124,7 @@
|
||||||
"forcepasswordchangenotice": "You must change your password to proceed.",
|
"forcepasswordchangenotice": "You must change your password to proceed.",
|
||||||
"fulllistofcourses": "All courses",
|
"fulllistofcourses": "All courses",
|
||||||
"fullnameandsitename": "{{fullname}} ({{sitename}})",
|
"fullnameandsitename": "{{fullname}} ({{sitename}})",
|
||||||
|
"fullscreen": "Fullscreen",
|
||||||
"group": "Group",
|
"group": "Group",
|
||||||
"groupsseparate": "Separate groups",
|
"groupsseparate": "Separate groups",
|
||||||
"groupsvisible": "Visible groups",
|
"groupsvisible": "Visible groups",
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { distinctUntilChanged, map } from 'rxjs/operators';
|
import { distinctUntilChanged, map } from 'rxjs/operators';
|
||||||
|
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { CoreEvents } from '@singletons/events';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Screen breakpoints.
|
* Screen breakpoints.
|
||||||
|
@ -48,6 +49,14 @@ export enum CoreScreenLayout {
|
||||||
TABLET = 'tablet',
|
TABLET = 'tablet',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Screen orientation.
|
||||||
|
*/
|
||||||
|
export enum CoreScreenOrientation {
|
||||||
|
LANDSCAPE = 'landscape',
|
||||||
|
PORTRAIT = 'portrait',
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage application screen.
|
* Manage application screen.
|
||||||
*/
|
*/
|
||||||
|
@ -93,6 +102,32 @@ export class CoreScreenService {
|
||||||
return this.layout === CoreScreenLayout.TABLET;
|
return this.layout === CoreScreenLayout.TABLET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get orientation(): CoreScreenOrientation {
|
||||||
|
const mql = window.matchMedia('(orientation: portrait)');
|
||||||
|
|
||||||
|
return mql.matches ? CoreScreenOrientation.PORTRAIT : CoreScreenOrientation.LANDSCAPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isPortrait(): boolean {
|
||||||
|
return this.orientation === CoreScreenOrientation.PORTRAIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isLandscape(): boolean {
|
||||||
|
return this.orientation === CoreScreenOrientation.LANDSCAPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watch orientation changes.
|
||||||
|
*/
|
||||||
|
watchOrientation(): void {
|
||||||
|
// Listen media orientation CSS queries.
|
||||||
|
window.matchMedia('(orientation: portrait)').addEventListener('change', (m) => {
|
||||||
|
const orientation = m.matches ? CoreScreenOrientation.PORTRAIT : CoreScreenOrientation.LANDSCAPE;
|
||||||
|
|
||||||
|
CoreEvents.trigger(CoreEvents.ORIENTATION_CHANGE, { orientation });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Watch viewport changes.
|
* Watch viewport changes.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { CoreSite, CoreSiteInfoResponse, CoreSitePublicConfigResponse } from '@c
|
||||||
import { CoreFilepoolComponentFileEventData } from '@services/filepool';
|
import { CoreFilepoolComponentFileEventData } from '@services/filepool';
|
||||||
import { CoreNavigationOptions } from '@services/navigator';
|
import { CoreNavigationOptions } from '@services/navigator';
|
||||||
import { CoreCourseModuleCompletionData } from '@features/course/services/course-helper';
|
import { CoreCourseModuleCompletionData } from '@features/course/services/course-helper';
|
||||||
|
import { CoreScreenOrientation } from '@services/screen';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Observer instance to stop listening to an event.
|
* Observer instance to stop listening to an event.
|
||||||
|
@ -55,6 +56,7 @@ export interface CoreEventsData {
|
||||||
[CoreEvents.COMPONENT_FILE_ACTION]: CoreFilepoolComponentFileEventData;
|
[CoreEvents.COMPONENT_FILE_ACTION]: CoreFilepoolComponentFileEventData;
|
||||||
[CoreEvents.FILE_SHARED]: CoreEventFileSharedData;
|
[CoreEvents.FILE_SHARED]: CoreEventFileSharedData;
|
||||||
[CoreEvents.APP_LAUNCHED_URL]: CoreEventAppLaunchedData;
|
[CoreEvents.APP_LAUNCHED_URL]: CoreEventAppLaunchedData;
|
||||||
|
[CoreEvents.ORIENTATION_CHANGE]: CoreEventOrientationData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -387,3 +389,10 @@ export type CoreEventFileSharedData = {
|
||||||
export type CoreEventAppLaunchedData = {
|
export type CoreEventAppLaunchedData = {
|
||||||
url: string;
|
url: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data passed to ORIENTATION_CHANGE event.
|
||||||
|
*/
|
||||||
|
export type CoreEventOrientationData = {
|
||||||
|
orientation: CoreScreenOrientation;
|
||||||
|
};
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
|
||||||
&::part(native) {
|
&::part(native) {
|
||||||
--inner-border-width: 0;
|
--inner-border-width: 0px;
|
||||||
--inner-padding-end: 0;
|
--inner-padding-end: 0px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,100 +50,93 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin border-start($px, $type: null, $color: null) {
|
@mixin border-start($px, $type: null, $color: null) {
|
||||||
@include ltr() {
|
border-left: $px $type $color;
|
||||||
border-left: $px $type $color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include rtl() {
|
@include rtl() {
|
||||||
|
border-left: unset;
|
||||||
border-right: $px $type $color;
|
border-right: $px $type $color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@mixin border-end($px, $type: null, $color: null) {
|
@mixin border-end($px, $type: null, $color: null) {
|
||||||
@include ltr() {
|
border-right: $px $type $color;
|
||||||
border-right: $px $type $color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include rtl() {
|
@include rtl() {
|
||||||
|
border-right: unset;
|
||||||
border-left: $px $type $color;
|
border-left: $px $type $color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin safe-area-border-start($px, $type, $color) {
|
@mixin safe-area-border-start($px, $type, $color) {
|
||||||
$safe-area-position: calc(constant(safe-area-inset-left) + #{$px});
|
$safe-area-position: calc(var(--ion-safe-area-left) + #{$px});
|
||||||
$safe-area-position-env: calc(env(safe-area-inset-left) + #{$px});
|
|
||||||
|
|
||||||
@include border-start($px, $type, $color);
|
@include border-start($safe-area-position, $type, $color);
|
||||||
@media screen and (orientation: landscape) {
|
|
||||||
@include border-start($safe-area-position, $type, $color);
|
|
||||||
@include border-start($safe-area-position-env, $type, $color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin safe-area-border-end($px, $type, $color) {
|
@mixin safe-area-border-end($px, $type, $color) {
|
||||||
$safe-area-position: calc(constant(safe-area-inset-right) + #{$px});
|
$safe-area-position: calc(var(--ion-safe-area-right) + #{$px});
|
||||||
$safe-area-position-env: calc(env(safe-area-inset-right) + #{$px});
|
|
||||||
|
|
||||||
@include border-end($px, $type, $color);
|
@include border-end($safe-area-position, $type, $color);
|
||||||
@media screen and (orientation: landscape) {
|
|
||||||
@include border-end($safe-area-position, $type, $color);
|
|
||||||
@include border-end($safe-area-position-env, $type, $color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin safe-area-margin-horizontal($start, $end: $start) {
|
@mixin safe-area-margin-horizontal($start, $end: $start) {
|
||||||
$safe-area-end: null;
|
$safe-area-end: null;
|
||||||
$safe-area-start: null;
|
$safe-area-start: null;
|
||||||
$safe-area-start-env: null;
|
|
||||||
$safe-area-end-env: null;
|
|
||||||
|
|
||||||
@if ($end) {
|
@if ($end) {
|
||||||
$safe-area-end: calc(constant(safe-area-inset-right) + #{$end});
|
$safe-area-end: calc(var(--ion-safe-area-right) + #{$end});
|
||||||
$safe-area-end-env: calc(env(safe-area-inset-right) + #{$end});
|
|
||||||
}
|
}
|
||||||
@if ($start) {
|
@if ($start) {
|
||||||
$safe-area-start: calc(constant(safe-area-inset-left) + #{$start});
|
$safe-area-start: calc(var(--ion-safe-area-left) + #{$start});
|
||||||
$safe-area-start-env: calc(env(safe-area-inset-left) + #{$start});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@include margin-horizontal($start, $end);
|
@include margin-horizontal($safe-area-start, $safe-area-end);
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (orientation: landscape) {
|
@mixin safe-area-margin-start($start, $end) {
|
||||||
@include margin-horizontal($safe-area-start, $safe-area-end);
|
$safe-area-start: calc(var(--ion-safe-area-left) + #{$start});
|
||||||
@include margin-horizontal($safe-area-start-env, $safe-area-end-env);
|
|
||||||
|
@include margin-horizontal($safe-area-start, $end);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin safe-area-margin-end($start, $end) {
|
||||||
|
$safe-area-end: calc(var(--ion-safe-area-right) + #{$end});
|
||||||
|
|
||||||
|
@include margin-horizontal($start, $safe-area-end);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin safe-area-padding-horizontal($start, $end: $start) {
|
||||||
|
$safe-area-end: null;
|
||||||
|
$safe-area-start: null;
|
||||||
|
|
||||||
|
@if ($end) {
|
||||||
|
$safe-area-end: calc(var(--ion-safe-area-right) + #{$end});
|
||||||
}
|
}
|
||||||
|
@if ($start) {
|
||||||
|
$safe-area-start: calc(var(--ion-safe-area-left) + #{$start});
|
||||||
|
}
|
||||||
|
|
||||||
|
@include padding-horizontal($safe-area-start, $safe-area-end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin safe-area-padding-start($start, $end) {
|
@mixin safe-area-padding-start($start, $end) {
|
||||||
$safe-area-start: calc(constant(safe-area-inset-left) + #{$start});
|
$safe-area-start: calc(var(--ion-safe-area-left) + #{$start});
|
||||||
$safe-area-start-env: calc(env(safe-area-inset-left) + #{$start});
|
|
||||||
|
|
||||||
@include padding-horizontal($start, $end);
|
@include padding-horizontal($safe-area-start, $end);
|
||||||
|
|
||||||
@media screen and (orientation: landscape) {
|
|
||||||
@include padding-horizontal($safe-area-start, $end);
|
|
||||||
@include padding-horizontal($safe-area-start-env, $end);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin safe-area-padding-end($start, $end) {
|
@mixin safe-area-padding-end($start, $end) {
|
||||||
$safe-area-end: calc(constant(safe-area-inset-right) + #{$end});
|
$safe-area-end: calc(var(--ion-safe-area-right) + #{$end});
|
||||||
$safe-area-end-env: calc(env(safe-area-inset-right) + #{$end});
|
|
||||||
|
|
||||||
@include padding-horizontal($start, $end);
|
@include padding-horizontal($start, $safe-area-end);
|
||||||
|
|
||||||
@media screen and (orientation: landscape) {
|
|
||||||
@include padding-horizontal($start, $safe-area-end);
|
|
||||||
@include padding-horizontal($start, $safe-area-end-env);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin safe-area-position($top: null, $end: null, $bottom: null, $start: null) {
|
@mixin safe-area-position($top: null, $end: null, $bottom: null, $start: null) {
|
||||||
@include position-horizontal($start, $end);
|
$safe-area-start: calc(var(--ion-safe-area-left) + #{$start});
|
||||||
@include safe-position-horizontal($start, $end);
|
$safe-area-end: calc(var(--ion-safe-area-right) + #{$end});
|
||||||
top: $top;
|
|
||||||
bottom: $bottom;
|
@include position($top, $safe-area-end, $bottom, $safe-area-start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin core-headings() {
|
@mixin core-headings() {
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
@import "./globals.scss";
|
@import "./globals.scss";
|
||||||
|
|
||||||
|
html.force-safe-area-margins {
|
||||||
|
--ion-safe-area-left: 40px;
|
||||||
|
--ion-safe-area-right: 40px;
|
||||||
|
--ion-safe-area-top: 40px;
|
||||||
|
--ion-safe-area-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo MOBILE-3790 non-standard property, doesn't work everywhere.
|
||||||
|
html {
|
||||||
|
zoom: var(--zoom-level);
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
-webkit-text-size-adjust: auto;
|
-webkit-text-size-adjust: var(--zoom-level);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common styles.
|
// Common styles.
|
||||||
|
@ -234,6 +246,10 @@ ion-header ion-toolbar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ion-footer ion-toolbar.ion-color-contrast {
|
||||||
|
background-color: var(--contrast-background);
|
||||||
|
}
|
||||||
|
|
||||||
// Ionic icon.
|
// Ionic icon.
|
||||||
ion-icon {
|
ion-icon {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -374,7 +390,48 @@ ion-list.list-md {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Safe areas
|
||||||
|
.safe-area-padding,
|
||||||
|
.safe-area-padding-horizontal {
|
||||||
|
@include padding-horizontal(var(--ion-safe-area-left), var(--ion-safe-area-right));
|
||||||
|
}
|
||||||
|
|
||||||
|
.safe-area-margin,
|
||||||
|
.safe-margin-horizontal {
|
||||||
|
@include margin-horizontal(var(--ion-safe-area-left), var(--ion-safe-area-right));
|
||||||
|
}
|
||||||
|
|
||||||
|
.ion-padding.safe-area-padding-horizontal {
|
||||||
|
@include safe-area-padding-horizontal(16px, 16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ion-margin.safe-margin-horizontal {
|
||||||
|
@include safe-area-margin-horizontal(16px, 16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
ion-tabs.placement-side .tabs-inner {
|
||||||
|
--ion-safe-area-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ion-tabs.placement-bottom .tabs-inner {
|
||||||
|
--ion-safe-area-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
core-split-view.menu-and-content {
|
||||||
|
.menu {
|
||||||
|
--ion-safe-area-right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-outlet {
|
||||||
|
--ion-safe-area-left: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Header.
|
// Header.
|
||||||
|
ion-header {
|
||||||
|
z-index: 12; // To hide ion-slides on scroll.
|
||||||
|
}
|
||||||
ion-tabs.hide-header ion-header {
|
ion-tabs.hide-header ion-header {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -384,6 +441,60 @@ ion-toolbar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iframe fullscreen manage.
|
||||||
|
// Using router outlet to avoid changing styles on modals.
|
||||||
|
body.core-iframe-fullscreen ion-router-outlet {
|
||||||
|
|
||||||
|
ion-tab-bar.mainmenu-tabs {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
// Restore original safe area.
|
||||||
|
.tabs-inner {
|
||||||
|
@supports (padding-left: constant(safe-area-inset-left)) {
|
||||||
|
--ion-safe-area-left: constant(safe-area-inset-left);
|
||||||
|
}
|
||||||
|
|
||||||
|
@supports (padding-left: env(safe-area-inset-left)) {
|
||||||
|
--ion-safe-area-left: env(safe-area-inset-left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--core-header-toolbar-height: 48px;
|
||||||
|
--core-header-toolbar-color: white;
|
||||||
|
--core-header-toolbar-background: black;
|
||||||
|
--core-header-toolbar-border-width: 0px;
|
||||||
|
|
||||||
|
ion-header ion-toolbar {
|
||||||
|
h1, ion-back-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (orientation: landscape) {
|
||||||
|
// Place ion-header on the side and hide text
|
||||||
|
.ion-page {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
ion-header {
|
||||||
|
width: calc(var(--core-header-toolbar-height), var(--ion-safe-area-right));
|
||||||
|
@include safe-area-padding-horizontal(null, 0px);
|
||||||
|
background: var(--core-header-toolbar-background);
|
||||||
|
|
||||||
|
ion-toolbar {
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
--padding-start: 0px;
|
||||||
|
--padding-end: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ion-buttons {
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Modals.
|
// Modals.
|
||||||
.core-modal-fullscreen .modal-wrapper {
|
.core-modal-fullscreen .modal-wrapper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -399,6 +510,8 @@ ion-toolbar {
|
||||||
|
|
||||||
@media only screen and (min-height: 400px) and (min-width: 300px) {
|
@media only screen and (min-height: 400px) and (min-width: 300px) {
|
||||||
.core-modal-lateral {
|
.core-modal-lateral {
|
||||||
|
--ion-safe-area-left: 0px;
|
||||||
|
--ion-safe-area-right: 0px;
|
||||||
|
|
||||||
.modal-wrapper {
|
.modal-wrapper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -434,9 +547,14 @@ ion-toolbar {
|
||||||
// Item styles
|
// Item styles
|
||||||
[aria-current="page"],
|
[aria-current="page"],
|
||||||
.item.item-current {
|
.item.item-current {
|
||||||
// TODO: Add safe area to border and RTL
|
@include safe-area-border-start(var(--selected-item-border-width), solid, var(--selected-item-color));
|
||||||
--ion-safe-area-left: calc(-1 * var(--selected-item-border-width));
|
> * {
|
||||||
border-inline-start: var(--selected-item-border-width) solid var(--selected-item-color);
|
--ion-safe-area-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::part(native) {
|
||||||
|
--ion-safe-area-left: 0px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item.item-file {
|
.item.item-file {
|
||||||
|
@ -467,7 +585,7 @@ ion-toolbar {
|
||||||
border-bottom: 3px solid var(--color-base);
|
border-bottom: 3px solid var(--color-base);
|
||||||
|
|
||||||
ion-item {
|
ion-item {
|
||||||
--inner-border-width: 0;
|
--inner-border-width: 0px;
|
||||||
}
|
}
|
||||||
ion-label {
|
ion-label {
|
||||||
white-space: normal !important;
|
white-space: normal !important;
|
||||||
|
@ -482,7 +600,7 @@ ion-toolbar {
|
||||||
|
|
||||||
--border-width: 0 0 3px 0;
|
--border-width: 0 0 3px 0;
|
||||||
--border-color: var(--color-base);
|
--border-color: var(--color-base);
|
||||||
--inner-border-width: 0;
|
--inner-border-width: 0px;
|
||||||
ion-icon {
|
ion-icon {
|
||||||
color: var(--color-base);
|
color: var(--color-base);
|
||||||
}
|
}
|
||||||
|
@ -528,7 +646,7 @@ img[core-external-content]:not([src]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-card ion-item:only-child {
|
ion-card ion-item:only-child {
|
||||||
--inner-border-width: 0;
|
--inner-border-width: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-course-module-handler:not(.addon-mod-label-handler) .item-heading .filter_mathjaxloader_equation div {
|
.core-course-module-handler:not(.addon-mod-label-handler) .item-heading .filter_mathjaxloader_equation div {
|
||||||
|
@ -686,10 +804,14 @@ core-block ion-item-divider .core-button-spinner {
|
||||||
|
|
||||||
// Horizontal scrolling elements
|
// Horizontal scrolling elements
|
||||||
.core-horizontal-scroll {
|
.core-horizontal-scroll {
|
||||||
display: flex;
|
display: block;
|
||||||
flex-flow: nowrap;
|
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
flex-direction: row;
|
.safe-area-pseudo-padding-start {
|
||||||
|
@include padding-horizontal(var(--ion-safe-area-left), 0px);
|
||||||
|
}
|
||||||
|
.safe-area-pseudo-padding-end {
|
||||||
|
@include padding-horizontal(0px, var(--ion-safe-area-right));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text formats.
|
// Text formats.
|
||||||
|
@ -952,6 +1074,11 @@ ion-item.item-input ion-input.has-focus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ionic set this value to 0 without px that provoked miscalculations.
|
||||||
|
ion-item-divider {
|
||||||
|
--inner-padding-end: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
// Change default outline.
|
// Change default outline.
|
||||||
:focus-visible {
|
:focus-visible {
|
||||||
@include core-focus-style();
|
@include core-focus-style();
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
--a11y-min-target-size: 44px;
|
--a11y-min-target-size: 44px;
|
||||||
--a11y-focus-color: var(--primary);
|
--a11y-focus-color: var(--primary);
|
||||||
--a11y-focus-width: 2px;
|
--a11y-focus-width: 2px;
|
||||||
|
--zoom-level: 100%;
|
||||||
|
|
||||||
--module-icon-size: 24px;
|
--module-icon-size: 24px;
|
||||||
|
|
||||||
|
@ -236,12 +237,17 @@
|
||||||
--color: var(--subdued-text-color);
|
--color: var(--subdued-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ion-back-button {
|
||||||
|
--min-height: var(--a11y-min-target-size);
|
||||||
|
--min-width: var(--a11y-min-target-size);
|
||||||
|
}
|
||||||
|
|
||||||
--core-combobox-background: var(--ion-item-background);
|
--core-combobox-background: var(--ion-item-background);
|
||||||
--core-combobox-color: var(--black);
|
--core-combobox-color: var(--black);
|
||||||
--core-combobox-border-color: var(--primary);
|
--core-combobox-border-color: var(--primary);
|
||||||
--core-combobox-border-width: 3px;
|
--core-combobox-border-width: 3px;
|
||||||
--core-combobox-border-all-width: 0 0 var(--core-combobox-border-width) 0;
|
--core-combobox-border-all-width: 0 0 var(--core-combobox-border-width) 0;
|
||||||
--core-combobox-radius: 0;
|
--core-combobox-radius: 0px;
|
||||||
--core-combobox-box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12);
|
--core-combobox-box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12);
|
||||||
|
|
||||||
--selected-item-color: var(--primary);
|
--selected-item-color: var(--primary);
|
||||||
|
|
Loading…
Reference in New Issue