commit
7aae777e89
|
@ -79,7 +79,7 @@
|
|||
|
||||
<!-- Subquestion -->
|
||||
<ion-radio-group [(ngModel)]="answers[question.name]" [required]="question.required" [name]="question.name">
|
||||
<ion-row *ngIf="question.parent !== 0" class="ion-align-items-center ion-padding" [class.even]="isEven">
|
||||
<ion-row *ngIf="question.parent !== 0" class="ion-align-items-center ion-padding-horizontal" [class.even]="isEven">
|
||||
|
||||
<ion-col size="7">
|
||||
<ion-label id="addon-mod_survey-{{question.id}}">
|
||||
|
@ -91,9 +91,10 @@
|
|||
|
||||
<!-- Tablet view: radio buttons -->
|
||||
<ion-col class="ion-hide-md-down ion-text-center" size="1"
|
||||
*ngFor="let option of question.optionsArray; let value=index;">
|
||||
*ngFor="let option of question.optionsArray; let value=index;"
|
||||
>
|
||||
<!-- Empty slot to avoid errors on migration tslint checks -->
|
||||
<ion-radio [value]="value + 1" [attr.aria-labelledby]="'addon-mod_survey-'+question.id" slot="">
|
||||
<ion-radio [value]="value + 1" [attr.aria-label]="question.num + '. '+question.text + ': ' + option">
|
||||
</ion-radio>
|
||||
</ion-col>
|
||||
<ion-col class="ion-hide-md-up" size="5">
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
.even {
|
||||
background-color: var(--even-background);
|
||||
}
|
||||
|
||||
ion-radio {
|
||||
height: var(--a11y-min-target-size);
|
||||
width: var(--a11y-min-target-size);
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
:host-context(body.dark) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div *ngIf="ddQuestion && (ddQuestion.text || ddQuestion.text === '')" class="addon-qtype-ddwtos-container">
|
||||
<div *ngIf="ddQuestion && (ddQuestion.text || ddQuestion.text === '')">
|
||||
<!-- Content is outside the core-loading to let the script calculate drag items position -->
|
||||
<core-loading [hideUntil]="ddQuestion.loaded"></core-loading>
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
|||
<ion-label>{{ 'core.question.howtodraganddrop' | translate }}</ion-label>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
<div class="addon-qtype-ddwtos-container">
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="ddQuestion.text"
|
||||
[contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" #questiontext
|
||||
(afterRender)="textRendered()">
|
||||
|
@ -20,6 +21,7 @@
|
|||
</core-format-text>
|
||||
|
||||
<div class="drags"></div>
|
||||
</div>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// Style ddwtos content a bit. Almost all these styles are copied from Moodle.
|
||||
.addon-qtype-ddwtos-container {
|
||||
min-height: 80px; // To display the loading.
|
||||
position: relative;
|
||||
}
|
||||
|
||||
core-format-text ::ng-deep, .drags ::ng-deep {
|
||||
|
|
|
@ -61,7 +61,6 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft
|
|||
numTabsShown = 0;
|
||||
direction = 'ltr';
|
||||
description = '';
|
||||
lastScroll = 0;
|
||||
slidesOpts = {
|
||||
initialSlide: 0,
|
||||
slidesPerView: 3,
|
||||
|
@ -89,6 +88,8 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft
|
|||
protected slidesSwiper: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
protected slidesSwiperLoaded = false;
|
||||
protected scrollElements: Record<string | number, HTMLElement> = {}; // Scroll elements for each loaded tab.
|
||||
protected lastScroll = 0;
|
||||
protected previousLastScroll = 0;
|
||||
|
||||
tabAction: CoreTabsRoleTab<T>;
|
||||
|
||||
|
@ -164,6 +165,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft
|
|||
this.tabBarElement!.classList.remove('tabs-hidden');
|
||||
if (scroll === 0) {
|
||||
this.tabBarElement!.style.height = '';
|
||||
this.previousLastScroll = this.lastScroll;
|
||||
this.lastScroll = 0;
|
||||
} else if (scroll !== undefined) {
|
||||
this.tabBarElement!.style.height = (this.tabBarHeight - scroll) + 'px';
|
||||
|
@ -253,18 +255,14 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft
|
|||
return;
|
||||
}
|
||||
|
||||
if (!this.tabsShown) {
|
||||
if (window.innerHeight >= CoreTabsBaseComponent.MAX_HEIGHT_TO_HIDE_TABS) {
|
||||
// Ensure tabbar is shown.
|
||||
this.tabsShown = true;
|
||||
this.tabBarElement?.classList.remove('tabs-hidden');
|
||||
this.lastScroll = 0;
|
||||
this.applyScroll(true, 0);
|
||||
this.calculateTabBarHeight();
|
||||
} else {
|
||||
} else if (!this.tabsShown) {
|
||||
// Don't recalculate.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await this.calculateMaxSlides();
|
||||
|
||||
|
@ -504,7 +502,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft
|
|||
return;
|
||||
}
|
||||
|
||||
if (scrollTop == this.lastScroll) {
|
||||
if (scrollTop == this.lastScroll || scrollTop == this.previousLastScroll) {
|
||||
// Ensure scroll has been modified to avoid flicks.
|
||||
return;
|
||||
}
|
||||
|
@ -522,6 +520,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft
|
|||
}
|
||||
|
||||
// Use lastScroll after moving the tabs to avoid flickering.
|
||||
this.previousLastScroll = this.lastScroll;
|
||||
this.lastScroll = scrollTop;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
<ion-spinner color="primary"></ion-spinner>
|
||||
<p class="core-loading-message" *ngIf="message" role="status">{{message}}</p>
|
||||
</div>
|
||||
<div #content class="core-loading-content" [id]="uniqueId" [attr.aria-busy]="hideUntil" [@coreShowHideAnimation]>
|
||||
<ng-content *ngIf="hideUntil">
|
||||
<div #content class="core-loading-content" [id]="uniqueId" [attr.aria-busy]="!hideUntil" [@coreShowHideAnimation]
|
||||
[class.opacity-hide]="!hideUntil">
|
||||
<ng-content *ngIf="loaded">
|
||||
</ng-content>
|
||||
</div>
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.core-loading-content {
|
||||
@include core-transition(opacity, 200ms);
|
||||
}
|
||||
|
||||
.core-loading-message {
|
||||
@include margin(10px, 0, 0, 0);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit {
|
|||
|
||||
uniqueId: string;
|
||||
protected element: HTMLElement; // Current element.
|
||||
loaded = false; // Only comes true once.
|
||||
|
||||
constructor(element: ElementRef) {
|
||||
this.element = element.nativeElement;
|
||||
|
@ -83,6 +84,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit {
|
|||
if (this.hideUntil) {
|
||||
this.element.classList.add('core-loading-loaded');
|
||||
}
|
||||
this.loaded = !!this.hideUntil;
|
||||
|
||||
this.content?.nativeElement.classList.toggle('core-loading-content', !!this.hideUntil);
|
||||
}
|
||||
|
@ -94,6 +96,10 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit {
|
|||
*/
|
||||
ngOnChanges(changes: { [name: string]: SimpleChange }): void {
|
||||
if (changes.hideUntil) {
|
||||
if (!this.loaded) {
|
||||
this.loaded = !!this.hideUntil; // Only comes true once.
|
||||
}
|
||||
|
||||
if (this.hideUntil) {
|
||||
setTimeout(() => {
|
||||
// Content is loaded so, center the spinner on the content itself.
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<span class="sr-only">{{ 'core.login.sitebadgedescription' | translate:{ count: site.badge } }}</span>
|
||||
</ion-badge>
|
||||
<ion-button *ngIf="showDelete" slot="end" fill="clear" color="danger" (click)="deleteSite($event, site)"
|
||||
[attr.aria-label]="'core.delete' | translate">
|
||||
[attr.aria-label]="'core.delete' | translate" [@coreSlideInOut]="'fromRight'">
|
||||
<ion-icon name="fas-trash" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
|
|
|
@ -22,6 +22,7 @@ import { CoreLoginHelper } from '@features/login/services/login-helper';
|
|||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
|
||||
import { CoreFilter } from '@features/filter/services/filter';
|
||||
import { CoreAnimations } from '@components/animations';
|
||||
|
||||
/**
|
||||
* Page that displays a "splash screen" while the app is being initialized.
|
||||
|
@ -29,6 +30,7 @@ import { CoreFilter } from '@features/filter/services/filter';
|
|||
@Component({
|
||||
selector: 'page-core-login-sites',
|
||||
templateUrl: 'sites.html',
|
||||
animations: [CoreAnimations.SLIDE_IN_OUT],
|
||||
})
|
||||
export class CoreLoginSitesPage implements OnInit {
|
||||
|
||||
|
|
|
@ -63,8 +63,11 @@ export class CoreSettingsHelperProvider {
|
|||
protected syncPromises: { [s: string]: Promise<void> } = {};
|
||||
protected prefersDark?: MediaQueryList;
|
||||
protected colorSchemes: CoreColorScheme[] = [];
|
||||
protected currentColorScheme = CoreColorScheme.LIGHT;
|
||||
|
||||
constructor() {
|
||||
this.prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
|
||||
if (!CoreConstants.CONFIG.forceColorScheme) {
|
||||
// Update color scheme when a user enters or leaves a site, or when the site info is updated.
|
||||
const applySiteScheme = (): void => {
|
||||
|
@ -72,7 +75,6 @@ export class CoreSettingsHelperProvider {
|
|||
// Dark mode is disabled, force light mode.
|
||||
this.setColorScheme(CoreColorScheme.LIGHT);
|
||||
} else {
|
||||
this.prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
// Reset color scheme settings.
|
||||
this.initColorScheme();
|
||||
}
|
||||
|
@ -86,7 +88,12 @@ export class CoreSettingsHelperProvider {
|
|||
// Reset color scheme settings.
|
||||
this.initColorScheme();
|
||||
});
|
||||
} else {
|
||||
this.initColorScheme();
|
||||
}
|
||||
|
||||
// Listen for changes to the prefers-color-scheme media query.
|
||||
this.prefersDark.addEventListener && this.prefersDark.addEventListener('change', this.toggleDarkModeListener.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -432,17 +439,10 @@ export class CoreSettingsHelperProvider {
|
|||
* @param colorScheme Name of the color scheme.
|
||||
*/
|
||||
setColorScheme(colorScheme: CoreColorScheme): void {
|
||||
this.currentColorScheme = colorScheme;
|
||||
if (colorScheme == CoreColorScheme.SYSTEM && this.prefersDark) {
|
||||
// Listen for changes to the prefers-color-scheme media query.
|
||||
this.prefersDark.addEventListener &&
|
||||
this.prefersDark.addEventListener('change', this.toggleDarkModeListener);
|
||||
|
||||
this.toggleDarkMode(this.prefersDark.matches);
|
||||
} else {
|
||||
// Stop listening to changes.
|
||||
this.prefersDark?.removeEventListener &&
|
||||
this.prefersDark?.removeEventListener('change', this.toggleDarkModeListener);
|
||||
|
||||
this.toggleDarkMode(colorScheme == CoreColorScheme.DARK);
|
||||
}
|
||||
}
|
||||
|
@ -460,11 +460,9 @@ export class CoreSettingsHelperProvider {
|
|||
|
||||
/**
|
||||
* Listener function to toggle dark mode.
|
||||
*
|
||||
* @param e Event object.
|
||||
*/
|
||||
protected toggleDarkModeListener = (e: MediaQueryListEvent): void => {
|
||||
document.body.classList.toggle('dark', e.matches);
|
||||
protected toggleDarkModeListener(): void {
|
||||
this.setColorScheme(this.currentColorScheme);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -654,10 +654,17 @@ export class CoreAppProvider {
|
|||
|
||||
const useLightText = CoreColors.isWhiteContrastingBetter(color);
|
||||
const statusBar = StatusBar.instance;
|
||||
statusBar.backgroundColorByHexString(color);
|
||||
useLightText ? statusBar.styleLightContent() : statusBar.styleDefault();
|
||||
|
||||
this.isIOS() && statusBar.overlaysWebView(false);
|
||||
|
||||
// styleDefault will use white text on iOS when darkmode is on. Force the background to black.
|
||||
if (this.isIOS() && !useLightText && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
statusBar.backgroundColorByHexString('#000000');
|
||||
statusBar.styleLightContent();
|
||||
} else {
|
||||
statusBar.backgroundColorByHexString(color);
|
||||
useLightText ? statusBar.styleLightContent() : statusBar.styleDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -180,6 +180,11 @@ core-format-text {
|
|||
ion-icon {
|
||||
flex: 1;
|
||||
align-self: center;
|
||||
/** Fix iOS icon size */
|
||||
margin: 0 auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
@ -338,7 +343,6 @@ core-rich-text-editor .core-rte-editor {
|
|||
select,
|
||||
input:not([type=checkbox]):not([type=radio]):not([type=hidden]) {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
display: inline-block;
|
||||
border: 1px solid var(--gray-dark);
|
||||
background: var(--background-contrast);
|
||||
|
|
Loading…
Reference in New Issue