Merge pull request #3293 from moodlehq/integration

Integration
main
Juan Leyva 2022-05-24 15:31:02 +02:00 committed by GitHub
commit 87402c7da8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 134 additions and 29 deletions

View File

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<widget android-versionCode="40001" id="com.moodle.moodlemobile" ios-CFBundleVersion="4.0.0.1" version="4.0.0" versionCode="40001" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<widget android-versionCode="40100" id="com.moodle.moodlemobile" ios-CFBundleVersion="4.0.1.0" version="4.0.1" versionCode="40100" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>Moodle</name>
<description>Moodle official app</description>
<author email="mobile@moodle.com" href="http://moodle.com">Moodle Mobile team</author>
@ -27,7 +27,7 @@
<preference name="UIWebViewBounce" value="false" />
<preference name="DisallowOverscroll" value="true" />
<preference name="prerendered-icon" value="true" />
<preference name="AppendUserAgent" value="MoodleMobile 4.0.0 (40000)" />
<preference name="AppendUserAgent" value="MoodleMobile 4.0.1 (40100)" />
<preference name="BackupWebStorage" value="none" />
<preference name="ScrollEnabled" value="false" />
<preference name="KeyboardDisplayRequiresUserAction" value="false" />
@ -251,7 +251,7 @@
<true />
</edit-config>
<edit-config file="*-Info.plist" mode="merge" target="CFBundleShortVersionString">
<string>4.0.0</string>
<string>4.0.1</string>
</edit-config>
<edit-config file="*-Info.plist" mode="overwrite" target="CFBundleLocalizations">
<array>

View File

@ -1,8 +1,8 @@
{
"app_id": "com.moodle.moodlemobile",
"appname": "Moodle Mobile",
"versioncode": 40000,
"versionname": "4.0.0",
"versioncode": 40100,
"versionname": "4.0.1",
"cache_update_frequency_usually": 420000,
"cache_update_frequency_often": 1200000,
"cache_update_frequency_sometimes": 3600000,

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "moodlemobile",
"version": "4.0.0",
"version": "4.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "moodlemobile",
"version": "4.0.0",
"version": "4.0.1",
"license": "Apache-2.0",
"dependencies": {
"@angular/animations": "10.0.14",

View File

@ -1,6 +1,6 @@
{
"name": "moodlemobile",
"version": "4.0.0",
"version": "4.0.1",
"description": "The official app for Moodle.",
"author": {
"name": "Moodle Pty Ltd.",

View File

@ -28,9 +28,7 @@
</ion-item>
</ion-card>
<div class="addon-mod-imscp-container">
<core-iframe *ngIf="loaded" [src]="src" [showFullscreenOnToolbar]="true" [autoFullscreenOnRotate]="true"></core-iframe>
</div>
<core-iframe *ngIf="loaded" [src]="src" [showFullscreenOnToolbar]="true" [autoFullscreenOnRotate]="true"></core-iframe>
</core-loading>
<core-navigation-bar collapsible-footer appearOnBottom *ngIf="loaded && navigationItems.length > 1" [items]="navigationItems"

View File

@ -1,3 +1,4 @@
.addon-mod_url-embedded-url {
height: 100%;
display: contents;
}

View File

@ -14,6 +14,7 @@
import envJson from '@/assets/env.json';
import { EnvironmentConfig } from '@/types/config';
import { CoreBrowser } from '@singletons/browser';
/**
* Context levels enumeration.
@ -154,7 +155,8 @@ export class CoreConstants {
// @todo [4.0] This is not the proper way to check for development tools, we should rely only on the BUILD variable.
return this.BUILD.isDevelopment
|| this.BUILD.isTesting
|| this.CONFIG.versionname.includes('-dev');
|| this.CONFIG.versionname.includes('-dev')
|| CoreBrowser.hasDevelopmentSetting('DevTools');
}
}

View File

@ -29,7 +29,6 @@ import { CoreFilepool, CoreFilepoolFileActions, CoreFilepoolFileEventData } from
import { CoreSites } from '@services/sites';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUtils } from '@services/utils/utils';
import { Platform } from '@singletons';
import { CoreLogger } from '@singletons/logger';
import { CoreError } from '@classes/errors/error';
import { CoreSite } from '@classes/site';
@ -304,12 +303,10 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges, O
return;
}
const line = Platform.is('tablet') || CoreApp.isAndroid() ? 90 : 80;
// Position all subtitles to a percentage of video height.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Array.from(track.cues).forEach((cue: any) => {
Array.from(track.cues).forEach((cue: VTTCue) => {
cue.snapToLines = false;
cue.line = line;
cue.line = 90;
cue.size = 100; // This solves some Android issue.
});
// Delete listener.

View File

@ -20,6 +20,7 @@ import { CoreCoursesDashboard, CoreCoursesDashboardProvider } from '@features/co
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
import { IonRefresher } from '@ionic/angular';
import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreCourses } from '../../services/courses';
@ -90,7 +91,9 @@ export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy {
await CoreUtils.nextTicks(2);
this.myOverviewBlock = this.block?.dynamicComponent?.instance as AddonBlockMyOverviewComponent;
} catch {
} catch (error) {
CoreDomUtils.showErrorModal(error);
// Cannot get the blocks, just show the block if needed.
this.loadFallbackBlock();
}

View File

@ -18,6 +18,7 @@ import { CoreMainMenuHomeHandler, CoreMainMenuHomeHandlerToDisplay } from '@feat
import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons';
import { CoreLogger } from '@singletons/logger';
import { CoreCoursesDashboard } from '../dashboard';
/**
@ -30,6 +31,11 @@ export class CoreDashboardHomeHandlerService implements CoreMainMenuHomeHandler
name = 'CoreCoursesDashboard';
priority = 1200;
logger: CoreLogger;
constructor() {
this.logger = CoreLogger.getInstance('CoreDashboardHomeHandlerService');
}
/**
* Check if the handler is enabled on a site level.
@ -59,9 +65,17 @@ export class CoreDashboardHomeHandlerService implements CoreMainMenuHomeHandler
const dashboardEnabled = !dashboardDisabled && dashboardConfig !== '0';
if (dashboardAvailable && dashboardEnabled && !blocksDisabled) {
const blocks = await CoreCoursesDashboard.getDashboardBlocks(undefined, siteId);
try {
const blocks = await CoreCoursesDashboard.getDashboardBlocks(undefined, siteId);
return CoreBlockDelegate.hasSupportedBlock(blocks.mainBlocks) || CoreBlockDelegate.hasSupportedBlock(blocks.sideBlocks);
return CoreBlockDelegate.hasSupportedBlock(blocks.mainBlocks) ||
CoreBlockDelegate.hasSupportedBlock(blocks.sideBlocks);
} catch (error) {
// Error getting blocks, assume it's enabled.
this.logger.error('Error getting Dashboard blocks', error);
return true;
}
}
// Dashboard is enabled but not available, we will fake blocks.

View File

@ -15,6 +15,7 @@
import { ApplicationRef, NgZone as NgZoneService } from '@angular/core';
import { CorePushNotifications, CorePushNotificationsProvider } from '@features/pushnotifications/services/pushnotifications';
import { CoreApp, CoreAppProvider } from '@services/app';
import { CoreConfig, CoreConfigProvider } from '@services/config';
import { CoreCronDelegate, CoreCronDelegateService } from '@services/cron';
import { CoreDB, CoreDbProvider } from '@services/db';
import { CoreCustomURLSchemes, CoreCustomURLSchemesProvider } from '@services/urlschemes';
@ -24,6 +25,7 @@ type AutomatedTestsWindow = Window & {
appRef?: ApplicationRef;
appProvider?: CoreAppProvider;
dbProvider?: CoreDbProvider;
configProvider?: CoreConfigProvider;
cronProvider?: CoreCronDelegateService;
ngZone?: NgZoneService;
pushNotifications?: CorePushNotificationsProvider;
@ -34,6 +36,7 @@ function initializeAutomatedTestsWindow(window: AutomatedTestsWindow) {
window.appRef = Application.instance;
window.appProvider = CoreApp.instance;
window.dbProvider = CoreDB.instance;
window.configProvider = CoreConfig.instance;
window.cronProvider = CoreCronDelegate.instance;
window.ngZone = NgZone.instance;
window.pushNotifications = CorePushNotifications.instance;

View File

@ -16,9 +16,11 @@ import { CoreApp, CoreAppProvider } from '@services/app';
import { CoreConfig, CoreConfigProvider } from '@services/config';
import { CoreDB, CoreDbProvider } from '@services/db';
import { CoreCustomURLSchemes, CoreCustomURLSchemesProvider } from '@services/urlschemes';
import { CoreBrowser } from '@singletons/browser';
import { CoreConstants } from '../constants';
type DevelopmentWindow = Window & {
browser?: typeof CoreBrowser;
appProvider?: CoreAppProvider;
configProvider?: CoreConfigProvider;
dbProvider?: CoreDbProvider;
@ -26,6 +28,7 @@ type DevelopmentWindow = Window & {
};
function initializeDevelopmentWindow(window: DevelopmentWindow) {
window.browser = CoreBrowser;
window.appProvider = CoreApp.instance;
window.configProvider = CoreConfig.instance;
window.dbProvider = CoreDB.instance;

View File

@ -201,11 +201,11 @@ export class CoreConfigProvider {
* Load development config overrides.
*/
protected loadDevelopmentConfig(): void {
if (!CoreConstants.enableDevTools() || !CoreBrowser.hasCookie('MoodleAppConfig')) {
if (!CoreConstants.enableDevTools() || !CoreBrowser.hasDevelopmentSetting('Config')) {
return;
}
this.patchEnvironment(JSON.parse(CoreBrowser.getCookie('MoodleAppConfig') ?? '{}'), { patchDefault: true });
this.patchEnvironment(JSON.parse(CoreBrowser.getDevelopmentSetting('Config') ?? '{}'), { patchDefault: true });
}
/**

View File

@ -36,7 +36,7 @@ export class CoreDbProvider {
* @returns Whether queries should be logged.
*/
loggingEnabled(): boolean {
return CoreBrowser.hasCookie('MoodleAppDBLoggingEnabled') || CoreAppProvider.isAutomated();
return CoreBrowser.hasDevelopmentSetting('DBLoggingEnabled') || CoreAppProvider.isAutomated();
}
/**

View File

@ -557,14 +557,14 @@ export class CoreSitesProvider {
}
// Add site to sites list.
this.addSite(siteId, siteUrl, token, info, privateToken, config, oauthId);
await this.addSite(siteId, siteUrl, token, info, privateToken, config, oauthId);
this.sites[siteId] = candidateSite;
if (login) {
// Turn candidate site into current site.
this.currentSite = candidateSite;
// Store session.
this.login(siteId);
await this.login(siteId);
} else if (this.currentSite && this.currentSite.getId() == siteId) {
// Current site has just been updated, trigger the event.
CoreEvents.trigger(CoreEvents.SITE_UPDATED, info, siteId);

View File

@ -27,6 +27,28 @@ export class CoreBrowser {
return new RegExp(`(\\s|;|^)${name}=`).test(document.cookie ?? '');
}
/**
* Check whether a development setting is set.
*
* @param name Setting name.
* @returns Whether the development setting is set.
*/
static hasDevelopmentSetting(name: string): boolean {
const setting = this.getDevelopmentSettingKey(name);
return this.hasCookie(setting) || this.hasLocalStorage(setting);
}
/**
* Check whether the given localStorage key is set.
*
* @param key localStorage key.
* @returns Whether the key is set.
*/
static hasLocalStorage(key: string): boolean {
return localStorage.getItem(key) !== null;
}
/**
* Read a cookie.
*
@ -45,4 +67,60 @@ export class CoreBrowser {
return cookies[name] ?? null;
}
/**
* Read a localStorage key.
*
* @param key localStorage key.
* @return localStorage value.
*/
static getLocalStorage(key: string): string | null {
return localStorage.getItem(key);
}
/**
* Get development setting value.
*
* @param name Setting name.
* @returns Development setting value.
*/
static getDevelopmentSetting(name: string): string | null {
const setting = this.getDevelopmentSettingKey(name);
return this.getCookie(setting) ?? this.getLocalStorage(setting);
}
/**
* Set development setting.
*
* @param name Setting name.
* @param value Setting value.
*/
static setDevelopmentSetting(name: string, value: string): void {
const setting = this.getDevelopmentSettingKey(name);
document.cookie = `${setting}=${value};path=/`;
localStorage.setItem(setting, value);
}
/**
* Unset development setting.
*
* @param name Setting name.
*/
static clearDevelopmentSetting(name: string): void {
const setting = this.getDevelopmentSettingKey(name);
document.cookie = `${setting}=;path=/;expires=Thu, 01 Jan 1970 00:00:01 GMT`;
localStorage.removeItem(setting);
}
/**
* Get development setting key.
*
* @param name Development setting name.
*/
protected static getDevelopmentSettingKey(name: string): string {
return `MoodleApp${name}`;
}
}

View File

@ -69,7 +69,7 @@ export class CoreLogger {
static getInstance(className: string): CoreLogger {
// Disable log on production and testing.
if (
!CoreBrowser.hasCookie('MoodleAppLoggingEnabled') &&
!CoreBrowser.hasDevelopmentSetting('LoggingEnabled') &&
(CoreConstants.BUILD.isProduction || CoreConstants.BUILD.isTesting)
) {
if (CoreConstants.BUILD.isProduction) {

View File

@ -147,9 +147,10 @@
// If the selector contains :host it means it is targeting just the host
// element so we can change it to look for host-context
} @else if str-contains($selector, ":host") {
$list: append($list, ":host-context(#{$addHostSelector})", comma);
// If the selector does not contain host at all it is either a shadow
// or normal element so append both the dir check and host-context
$shadow-element: str-replace($selector, ":host", ":host-context(#{$addHostSelector})");
$list: append($list, $shadow-element, comma);
// If the selector does not contain host at all it is either a shadow
// or normal element so append both the dir check and host-context
} @else {
$list: append($list, "#{$addHostSelector} #{$selector}", comma);
$list: append($list, ":host-context(#{$addHostSelector}) #{$selector}", comma);

View File

@ -1725,3 +1725,8 @@ ion-header.no-title {
bottom: 0;
}
}
// Fix subtitles wider than video.
video::-webkit-media-text-track-display {
white-space: normal !important;
}