Merge pull request #3066 from crazyserver/MOBILE-3814

Mobile 3814
main
Dani Palou 2022-01-24 09:30:30 +01:00 committed by GitHub
commit 5a2016cb67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 98 additions and 34 deletions

View File

@ -1515,7 +1515,6 @@
"core.course.confirmdownloadzerosize": "local_moodlemobileapp",
"core.course.confirmlimiteddownload": "local_moodlemobileapp",
"core.course.confirmpartialdownloadsize": "local_moodlemobileapp",
"core.course.contents": "local_moodlemobileapp",
"core.course.couldnotloadsectioncontent": "local_moodlemobileapp",
"core.course.couldnotloadsections": "local_moodlemobileapp",
"core.course.coursesummary": "moodle",
@ -2274,7 +2273,6 @@
"core.updaterequireddesc": "local_moodlemobileapp",
"core.upgraderunning": "error",
"core.user": "moodle",
"core.user.account": "local_moodlemobileapp",
"core.user.address": "moodle",
"core.user.city": "moodle",
"core.user.contact": "local_moodlemobileapp",
@ -2300,6 +2298,7 @@
"core.user.sendemail": "local_moodlemobileapp",
"core.user.student": "moodle/defaultcoursestudent",
"core.user.teacher": "moodle/noneditingteacher",
"core.user.useraccount": "moodle",
"core.user.userwithid": "local_moodlemobileapp",
"core.user.webpage": "moodle",
"core.userdeleted": "moodle",

View File

@ -26,7 +26,6 @@
"confirmdownloadzerosize": "You are about to start downloading.{{availableSpace}} Are you sure you want to continue?",
"confirmpartialdownloadsize": "You are about to download <strong>at least</strong> {{size}}.{{availableSpace}} Are you sure you want to continue?",
"confirmlimiteddownload": "You are not currently connected to Wi-Fi. ",
"contents": "Contents",
"gotonextactivity": "Continue to next activity",
"gotonextactivitynotfound": "Next activity not found. It's possible that it has been hidden or deleted.",
"gotopreviousactivity": "Continue to previous activity",

View File

@ -385,7 +385,7 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy {
openCourseSummary(): void {
CoreNavigator.navigateToSitePath(
'/course/' + this.course.id + '/preview',
{ params: { course: this.course, avoidOpenCourse: true } },
{ params: { course: this.course } },
);
}

View File

@ -51,7 +51,7 @@ export class CoreCourseIndexPage implements OnInit, OnDestroy {
protected isGuest?: boolean;
protected contentsTab: CoreTabsOutletTab = {
page: CONTENTS_PAGE_NAME,
title: 'core.course.contents',
title: 'core.course',
pageParams: {},
};

View File

@ -21,8 +21,8 @@
</div>
</div>
<div class="core-course-thumb-parallax-content" *ngIf="course">
<ion-item class="ion-text-wrap" (click)="openCourse()" [attr.aria-label]="course.fullname"
[detail]="!avoidOpenCourse && canAccessCourse" [button]="!avoidOpenCourse && canAccessCourse">
<ion-item class="ion-text-wrap" (click)="openCourse()" [attr.aria-label]="course.fullname" [detail]="canAccessCourse"
[button]="canAccessCourse">
<ion-icon name="fas-graduation-cap" fixed-width slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>
@ -121,11 +121,10 @@
<h2 *ngIf="prefetchCourseData.status == statusDownloaded">{{ 'core.course.refreshcourse' | translate }}</h2>
</ion-label>
</ion-item>
<ion-item button (click)="openCourse()" [attr.aria-label]="course.fullname" *ngIf="!avoidOpenCourse && canAccessCourse"
detail="true">
<ion-item button (click)="openCourse()" [attr.aria-label]="course.fullname" *ngIf="canAccessCourse" detail="true">
<ion-icon name="fas-briefcase" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ 'core.course.contents' | translate }}</h2>
<h2>{{ 'core.course' | translate }}</h2>
</ion-label>
</ion-item>
<ion-item [href]="courseUrl" core-link [attr.aria-label]="course.fullname" button detail="false" [showBrowserWarning]="false">

View File

@ -51,7 +51,6 @@ export class CoreCoursePreviewPage implements OnInit, OnDestroy {
selfEnrolInstances: CoreCourseEnrolmentMethod[] = [];
paypalEnabled = false;
dataLoaded = false;
avoidOpenCourse = false;
prefetchCourseData: CorePrefetchStatusInfo = {
icon: '',
statusTranslatable: 'core.loading',
@ -97,7 +96,6 @@ export class CoreCoursePreviewPage implements OnInit, OnDestroy {
*/
async ngOnInit(): Promise<void> {
this.course = CoreNavigator.getRouteParam('course');
this.avoidOpenCourse = !!CoreNavigator.getRouteBooleanParam('avoidOpenCourse');
if (!this.course) {
CoreNavigator.back();
@ -238,8 +236,7 @@ export class CoreCoursePreviewPage implements OnInit, OnDestroy {
* Open the course.
*/
openCourse(): void {
if (!this.canAccessCourse || this.avoidOpenCourse) {
// Course cannot be opened or we are avoiding opening because we accessed from inside a course.
if (!this.canAccessCourse) {
return;
}

View File

@ -4,7 +4,10 @@
<ion-back-button [text]="'core.back' | translate"></ion-back-button>
</ion-buttons>
<ion-title>
<h1>{{ 'core.courses.mycourses' | translate }}</h1>
<h1>
<core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0"></core-format-text>
<img src="assets/img/top_logo.png" class="core-header-logo" [alt]="siteName">
</h1>
</ion-title>
<ion-buttons slot="end">
<ion-button *ngIf="searchEnabled" (click)="openSearch()" [attr.aria-label]="'core.courses.searchcourses' | translate">
@ -30,6 +33,9 @@
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher>
<core-loading [hideUntil]="loaded">
<div class="ion-padding-horizontal">
<h2>{{ 'core.courses.mycourses' | translate }}</h2>
</div>
<ion-list>
<core-block *ngIf="loadedBlock?.visible" [block]="loadedBlock" contextLevel="user" [instanceId]="userId"
[extraData]="{'downloadEnabled': true}"></core-block>

View File

@ -36,6 +36,7 @@ export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy {
@ViewChild(CoreBlockComponent) block!: CoreBlockComponent;
siteName = '';
searchEnabled = false;
downloadCoursesEnabled = false;
userId: number;
@ -50,6 +51,8 @@ export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy {
this.updateSiteObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => {
this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite();
this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite();
this.loadSiteName();
}, CoreSites.getCurrentSiteId());
this.userId = CoreSites.getCurrentSiteUserId();
@ -62,8 +65,9 @@ export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy {
this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite();
this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite();
this.loadContent();
this.loadSiteName();
this.loadContent();
}
/**
@ -97,6 +101,13 @@ export class CoreCoursesMyCoursesPage implements OnInit, OnDestroy {
this.loaded = true;
}
/**
* Load the site name.
*/
protected loadSiteName(): void {
this.siteName = CoreSites.getRequiredCurrentSite().getSiteName() || '';
}
/**
* Load fallback blocks.
*/

View File

@ -1,3 +1,3 @@
<core-user-avatar *ngIf="isMainScreen && siteInfo" [user]="siteInfo" class="core-bar-button-image clickable" [linkProfile]="false"
(ariaButtonClick)="openUserMenu($event)" role="button" tabindex="0" [attr.aria-label]="'core.user.account' | translate">
(ariaButtonClick)="openUserMenu($event)" role="button" tabindex="0" [attr.aria-label]="'core.user.useraccount' | translate">
</core-user-avatar>

View File

@ -2,7 +2,7 @@
<ion-toolbar>
<ion-title>
<h2>
{{'core.user.account' | translate}}
{{'core.user.useraccount' | translate}}
</h2>
</ion-title>
<ion-buttons slot="end">
@ -17,6 +17,9 @@
<ion-item button class="core-usermenu-siteinfo ion-text-wrap" *ngIf="siteInfo" lines="full" detail="false" [href]="siteUrl"
core-link auto-login="yes">
<ion-label>
<!-- Show site logo. -->
<img class="core-usermenu-site-logo" *ngIf="siteLogo && siteLogoLoaded" [src]="siteLogo" role="presentation" alt=""
onError="this.class='image-not-found'">
<p class="core-usermenu-sitename">
<core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
</core-format-text>

View File

@ -8,6 +8,10 @@
}
.core-usermenu-siteinfo {
text-align: center;
ion-label {
margin: 0;
}
--padding-top: 10px;
--padding-bottom: 10px;
}
@ -19,9 +23,21 @@
}
.core-usermenu-sitename {
font-size: 16px;
font-weight: bold;
font-size: 20px;
line-height: 24px;
}
img.core-usermenu-site-logo {
margin-bottom: 8px;
max-height: var(--core-user-menu-site-logo-max-height);
}
img.image-not-found {
display: none;
}
@if ($core-user-hide-sitename) {
.core-usermenu-sitename {
display: none;

View File

@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { CoreConstants } from '@/core/constants';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { CoreSiteInfo } from '@classes/site';
import { CoreSite, CoreSiteInfo } from '@classes/site';
import { CoreLoginSitesComponent } from '@features/login/components/sites/sites';
import { CoreLoginHelper } from '@features/login/services/login-helper';
import { CoreUser, CoreUserProfile } from '@features/user/services/user';
@ -36,12 +37,13 @@ export class CoreMainMenuUserMenuComponent implements OnInit, OnDestroy {
siteInfo?: CoreSiteInfo;
siteName?: string;
siteLogo?: string;
siteLogoLoaded = false;
siteUrl?: string;
handlers: CoreUserProfileHandlerData[] = [];
handlersLoaded = false;
loaded = false;
user?: CoreUserProfile;
moreSites = false;
protected subscription!: Subscription;
@ -49,10 +51,6 @@ export class CoreMainMenuUserMenuComponent implements OnInit, OnDestroy {
* @inheritdoc
*/
async ngOnInit(): Promise<void> {
// Check if there are more sites to switch.
const sites = await CoreSites.getSites();
this.moreSites = sites.length > 1;
const currentSite = CoreSites.getRequiredCurrentSite();
this.siteInfo = currentSite.getInfo();
this.siteName = currentSite.getSiteName();
@ -60,6 +58,8 @@ export class CoreMainMenuUserMenuComponent implements OnInit, OnDestroy {
this.loaded = true;
this.loadSiteLogo(currentSite);
// Load the handlers.
if (this.siteInfo) {
this.user = await CoreUser.getProfile(this.siteInfo.userid);
@ -82,6 +82,31 @@ export class CoreMainMenuUserMenuComponent implements OnInit, OnDestroy {
}
}
/**
* Load site logo from current site public config.
*
* @param currentSite Current site object.
* @return Promise resolved when done.
*/
protected async loadSiteLogo(currentSite: CoreSite): Promise<void> {
if (CoreConstants.CONFIG.forceLoginLogo) {
this.siteLogo = 'assets/img/login_logo.png';
this.siteLogoLoaded = true;
return;
}
try {
const siteConfig = await currentSite.getPublicConfig();
this.siteLogo = CoreLoginHelper.getLogoUrl(siteConfig);
} catch {
// Ignore errors.
} finally {
this.siteLogoLoaded = true;
}
}
/**
* Opens User profile page.
*

View File

@ -55,7 +55,7 @@ export class CoreMainMenuHomePage implements OnInit {
}
/**
* Initialize the component.
* @inheritdoc
*/
ngOnInit(): void {
this.route.queryParams.subscribe((params: Partial<CoreRedirectPayload> & { urlToOpen?: string }) => {
@ -121,7 +121,7 @@ export class CoreMainMenuHomePage implements OnInit {
* Load the site name.
*/
protected loadSiteName(): void {
this.siteName = CoreSites.getCurrentSite()?.getSiteName() || '';
this.siteName = CoreSites.getRequiredCurrentSite().getSiteName() || '';
}
/**

View File

@ -13,12 +13,6 @@
<ion-content>
<ion-list>
<ion-item button class="ion-text-wrap" detail="false" (click)="openPage('deviceinfo')">
<ion-icon name="fas-mobile" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ appName }} {{ versionName }}</h2>
</ion-label>
</ion-item>
<ion-item button class="ion-text-wrap" (click)="openPage('licenses')" detail="true">
<ion-icon name="far-copyright" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'core.settings.opensourcelicenses' | translate }}</ion-label>
@ -40,3 +34,12 @@
</ion-item>
</ion-list>
</ion-content>
<ion-footer class="ion-no-border">
<ion-item button class="ion-text-wrap ion-text-center core-about-deviceinfo" detail="false" (click)="openPage('deviceinfo')"
lines="none">
<ion-label>
<h2>{{ appName }} {{ versionName }}</h2>
</ion-label>
</ion-item>
</ion-footer>

View File

@ -0,0 +1,3 @@
.core-about-deviceinfo {
--background: transparent;
}

View File

@ -24,6 +24,7 @@ import { CoreNavigator } from '@services/navigator';
@Component({
selector: 'page-core-app-settings-about',
templateUrl: 'about.html',
styleUrls: ['about.scss'],
})
export class CoreSettingsAboutPage {

View File

@ -1,6 +1,6 @@
{
"address": "Address",
"account": "Account",
"useraccount": "User account",
"city": "City/town",
"contact": "Contact",
"country": "Country",

View File

@ -264,6 +264,8 @@
--core-course-module-navigation-max-height: 56px;
--core-course-module-navigation-background: var(--contrast-background);
--core-user-menu-site-logo-max-height: 32px;
--addon-calendar-event-category-color: var(--purple);
--addon-calendar-event-course-color: var(--red);
--addon-calendar-event-group-color: var(--yellow);