forked from EVOgeek/Vmeda.Online
commit
0708081868
|
@ -87,7 +87,7 @@
|
||||||
"hammerjs": "2.0.8",
|
"hammerjs": "2.0.8",
|
||||||
"jszip": "3.7.1",
|
"jszip": "3.7.1",
|
||||||
"mathjax": "2.7.7",
|
"mathjax": "2.7.7",
|
||||||
"moment": "2.29.0",
|
"moment": "2.29.2",
|
||||||
"nl.kingsquare.cordova.background-audio": "1.0.1",
|
"nl.kingsquare.cordova.background-audio": "1.0.1",
|
||||||
"rxjs": "6.5.5",
|
"rxjs": "6.5.5",
|
||||||
"ts-md5": "1.2.7",
|
"ts-md5": "1.2.7",
|
||||||
|
@ -20984,9 +20984,9 @@
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"node_modules/moment": {
|
"node_modules/moment": {
|
||||||
"version": "2.29.0",
|
"version": "2.29.2",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz",
|
||||||
"integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA==",
|
"integrity": "sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
|
@ -47321,9 +47321,9 @@
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"moment": {
|
"moment": {
|
||||||
"version": "2.29.0",
|
"version": "2.29.2",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz",
|
||||||
"integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA=="
|
"integrity": "sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg=="
|
||||||
},
|
},
|
||||||
"move-concurrently": {
|
"move-concurrently": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
"hammerjs": "2.0.8",
|
"hammerjs": "2.0.8",
|
||||||
"jszip": "3.7.1",
|
"jszip": "3.7.1",
|
||||||
"mathjax": "2.7.7",
|
"mathjax": "2.7.7",
|
||||||
"moment": "2.29.0",
|
"moment": "2.29.2",
|
||||||
"nl.kingsquare.cordova.background-audio": "1.0.1",
|
"nl.kingsquare.cordova.background-audio": "1.0.1",
|
||||||
"rxjs": "6.5.5",
|
"rxjs": "6.5.5",
|
||||||
"ts-md5": "1.2.7",
|
"ts-md5": "1.2.7",
|
||||||
|
|
|
@ -56,6 +56,8 @@
|
||||||
<core-format-text [text]="discussion.subject" contextLevel="module" [contextInstanceId]="module && module.id"
|
<core-format-text [text]="discussion.subject" contextLevel="module" [contextInstanceId]="module && module.id"
|
||||||
[courseId]="courseId">
|
[courseId]="courseId">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
|
<ion-icon name="fas-lock" *ngIf="discussion.locked" class="addon-mod-forum-locked-icon"
|
||||||
|
[attr.aria-label]="'addon.mod_forum.discussionlocked' | translate"></ion-icon>
|
||||||
</p>
|
</p>
|
||||||
<ion-button *ngIf="canPin || discussion.canlock || discussion.canfavourite" fill="clear"
|
<ion-button *ngIf="canPin || discussion.canlock || discussion.canfavourite" fill="clear"
|
||||||
[attr.aria-label]="('core.displayoptions' | translate)" (click)="showOptionsMenu($event, discussion)">
|
[attr.aria-label]="('core.displayoptions' | translate)" (click)="showOptionsMenu($event, discussion)">
|
||||||
|
|
|
@ -18,6 +18,11 @@
|
||||||
|
|
||||||
ion-icon {
|
ion-icon {
|
||||||
@include margin(0, 6px, 0, 0);
|
@include margin(0, 6px, 0, 0);
|
||||||
|
|
||||||
|
&.addon-mod-forum-locked-icon {
|
||||||
|
@include margin-horizontal(4px, 0px);
|
||||||
|
color: var(--gray-500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,6 @@
|
||||||
<p class="item-heading" *ngIf="offlinePost">{{ 'core.discard' | translate }}</p>
|
<p class="item-heading" *ngIf="offlinePost">{{ 'core.discard' | translate }}</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap" *ngIf="wordCount">
|
|
||||||
<ion-label>
|
|
||||||
<p class="item-heading">{{ 'core.numwords' | translate: {'$a': wordCount} }}</p>
|
|
||||||
</ion-label>
|
|
||||||
</ion-item>
|
|
||||||
<ion-item class="ion-text-wrap" [href]="url" *ngIf="url" core-link capture="false" button detail="false" [showBrowserWarning]="false">
|
<ion-item class="ion-text-wrap" [href]="url" *ngIf="url" core-link capture="false" button detail="false" [showBrowserWarning]="false">
|
||||||
<ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
|
|
|
@ -34,7 +34,6 @@ export class AddonModForumPostOptionsMenuComponent implements OnInit, OnDestroy
|
||||||
@Input() cmId!: number;
|
@Input() cmId!: number;
|
||||||
@Input() forumId!: number; // The forum Id.
|
@Input() forumId!: number; // The forum Id.
|
||||||
|
|
||||||
wordCount?: number | null; // Number of words when available.
|
|
||||||
canEdit = false;
|
canEdit = false;
|
||||||
canDelete = false;
|
canDelete = false;
|
||||||
loaded = false;
|
loaded = false;
|
||||||
|
@ -89,7 +88,6 @@ export class AddonModForumPostOptionsMenuComponent implements OnInit, OnDestroy
|
||||||
|
|
||||||
this.canDelete = !!this.post.capabilities.delete && AddonModForum.isDeletePostAvailable();
|
this.canDelete = !!this.post.capabilities.delete && AddonModForum.isDeletePostAvailable();
|
||||||
this.canEdit = !!this.post.capabilities.edit && AddonModForum.isUpdatePostAvailable();
|
this.canEdit = !!this.post.capabilities.edit && AddonModForum.isUpdatePostAvailable();
|
||||||
this.wordCount = (this.post.haswordcount && this.post.wordcount) || null;
|
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,9 @@
|
||||||
<core-format-text [component]="component" [componentId]="componentId" [text]="post.message" contextLevel="module"
|
<core-format-text [component]="component" [componentId]="componentId" [text]="post.message" contextLevel="module"
|
||||||
[contextInstanceId]="forum && forum.cmid" [courseId]="courseId">
|
[contextInstanceId]="forum && forum.cmid" [courseId]="courseId">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
|
<p *ngIf="post.haswordcount && post.wordcount">
|
||||||
|
<em>{{ 'core.numwords' | translate: {'$a': post.wordcount} }}</em>
|
||||||
|
</p>
|
||||||
<div *ngIf="post.attachments && post.attachments.length > 0">
|
<div *ngIf="post.attachments && post.attachments.length > 0">
|
||||||
<core-files [files]="post.attachments" [component]="component" [componentId]="componentId" showInline="true">
|
<core-files [files]="post.attachments" [component]="component" [componentId]="componentId" showInline="true">
|
||||||
</core-files>
|
</core-files>
|
||||||
|
|
|
@ -41,6 +41,10 @@ const appRoutes: Routes = [
|
||||||
canActivate: [CoreMainMenuAuthGuard],
|
canActivate: [CoreMainMenuAuthGuard],
|
||||||
canLoad: [CoreMainMenuAuthGuard],
|
canLoad: [CoreMainMenuAuthGuard],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'reload',
|
||||||
|
loadChildren: () => import('./pages/reload/reload.module').then( m => m.CoreMainMenuReloadPageModule),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -30,6 +30,7 @@ import { NavigationEnd } from '@angular/router';
|
||||||
import { trigger, state, style, transition, animate } from '@angular/animations';
|
import { trigger, state, style, transition, animate } from '@angular/animations';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreDom } from '@singletons/dom';
|
import { CoreDom } from '@singletons/dom';
|
||||||
|
import { CoreLogger } from '@singletons/logger';
|
||||||
|
|
||||||
const ANIMATION_DURATION = 500;
|
const ANIMATION_DURATION = 500;
|
||||||
|
|
||||||
|
@ -84,6 +85,7 @@ export class CoreMainMenuPage implements OnInit, OnDestroy {
|
||||||
protected urlToOpen?: string;
|
protected urlToOpen?: string;
|
||||||
protected redirectPath?: string;
|
protected redirectPath?: string;
|
||||||
protected redirectOptions?: CoreNavigationOptions;
|
protected redirectOptions?: CoreNavigationOptions;
|
||||||
|
protected logger: CoreLogger;
|
||||||
|
|
||||||
@ViewChild('mainTabs') mainTabs?: IonTabs;
|
@ViewChild('mainTabs') mainTabs?: IonTabs;
|
||||||
|
|
||||||
|
@ -92,6 +94,7 @@ export class CoreMainMenuPage implements OnInit, OnDestroy {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.backButtonFunction = this.backButtonClicked.bind(this);
|
this.backButtonFunction = this.backButtonClicked.bind(this);
|
||||||
this.tabAction = new CoreMainMenuRoleTab(this);
|
this.tabAction = new CoreMainMenuRoleTab(this);
|
||||||
|
this.logger = CoreLogger.getInstance('CoreMainMenuPage');
|
||||||
|
|
||||||
// Listen navigation events to show or hide tabs.
|
// Listen navigation events to show or hide tabs.
|
||||||
this.navSubscription = Router.events
|
this.navSubscription = Router.events
|
||||||
|
@ -193,6 +196,7 @@ export class CoreMainMenuPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
const tabPage = this.tabs[0] ? this.tabs[0].page : this.morePageName;
|
const tabPage = this.tabs[0] ? this.tabs[0].page : this.morePageName;
|
||||||
const tabPageParams = this.tabs[0] ? this.tabs[0].pageParams : {};
|
const tabPageParams = this.tabs[0] ? this.tabs[0].pageParams : {};
|
||||||
|
this.logger.debug(`Select first tab: ${tabPage}.`, this.tabs);
|
||||||
|
|
||||||
// Use navigate instead of mainTabs.select to be able to pass page params.
|
// Use navigate instead of mainTabs.select to be able to pass page params.
|
||||||
CoreNavigator.navigate(tabPage, {
|
CoreNavigator.navigate(tabPage, {
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
<ion-content>
|
||||||
|
<core-loading></core-loading>
|
||||||
|
</ion-content>
|
|
@ -0,0 +1,37 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { CoreMainMenuReloadPage } from './reload';
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: CoreMainMenuReloadPage,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild(routes),
|
||||||
|
CoreSharedModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
CoreMainMenuReloadPage,
|
||||||
|
],
|
||||||
|
exports: [RouterModule],
|
||||||
|
})
|
||||||
|
export class CoreMainMenuReloadPageModule {}
|
|
@ -0,0 +1,36 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { CoreNavigator } from '@services/navigator';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page that displays a loading and then opens the main menu again.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'page-core-mainmenu-reload',
|
||||||
|
templateUrl: 'reload.html',
|
||||||
|
})
|
||||||
|
export class CoreMainMenuReloadPage implements OnInit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
ngOnInit(): void {
|
||||||
|
CoreNavigator.navigate('/main', {
|
||||||
|
reset: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ import { Diagnostic, Translate } from '@singletons';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { AlertButton } from '@ionic/angular';
|
import { AlertButton } from '@ionic/angular';
|
||||||
|
import { CoreNavigator } from '@services/navigator';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the general settings.
|
* Page that displays the general settings.
|
||||||
|
@ -168,7 +169,10 @@ export class CoreSettingsGeneralPage {
|
||||||
await CoreUtils.ignoreErrors(Promise.all(sites.map((site) => site.invalidateWsCache())));
|
await CoreUtils.ignoreErrors(Promise.all(sites.map((site) => site.invalidateWsCache())));
|
||||||
|
|
||||||
CoreEvents.trigger(CoreEvents.LANGUAGE_CHANGED, this.selectedLanguage);
|
CoreEvents.trigger(CoreEvents.LANGUAGE_CHANGED, this.selectedLanguage);
|
||||||
window.location.reload();
|
|
||||||
|
CoreNavigator.navigate('/reload', {
|
||||||
|
reset: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -76,7 +76,7 @@ export class CoreTimeUtilsProvider {
|
||||||
moment.relativeTimeThreshold('s', 60);
|
moment.relativeTimeThreshold('s', 60);
|
||||||
moment.relativeTimeThreshold('m', 60);
|
moment.relativeTimeThreshold('m', 60);
|
||||||
moment.relativeTimeThreshold('h', 24);
|
moment.relativeTimeThreshold('h', 24);
|
||||||
moment.relativeTimeThreshold('d', 31);
|
moment.relativeTimeThreshold('d', 30);
|
||||||
moment.relativeTimeThreshold('M', 12);
|
moment.relativeTimeThreshold('M', 12);
|
||||||
moment.relativeTimeThreshold('y', 365);
|
moment.relativeTimeThreshold('y', 365);
|
||||||
moment.relativeTimeThreshold('ss', 0); // To display exact number of seconds instead of just "a few seconds".
|
moment.relativeTimeThreshold('ss', 0); // To display exact number of seconds instead of just "a few seconds".
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import moment from 'moment';
|
import { Translate } from '@singletons';
|
||||||
|
import { CoreConstants } from '../constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton with helper functions for time operations.
|
* Singleton with helper functions for time operations.
|
||||||
|
@ -27,37 +28,54 @@ export class CoreTime {
|
||||||
* @return Seconds in a human readable format.
|
* @return Seconds in a human readable format.
|
||||||
*/
|
*/
|
||||||
static formatTime(seconds: number, precision = 2): string {
|
static formatTime(seconds: number, precision = 2): string {
|
||||||
precision = precision || 6; // Use max precision if 0 is passed.
|
precision = precision || 5; // Use max precision if 0 is passed.
|
||||||
|
|
||||||
const eventDuration = moment.duration(Math.abs(seconds), 'seconds');
|
const totalSecs = Math.abs(seconds);
|
||||||
let durationString = '';
|
if (!totalSecs) {
|
||||||
|
return Translate.instant('core.now');
|
||||||
|
}
|
||||||
|
|
||||||
if (precision && eventDuration.years() > 0) {
|
const years = Math.floor(totalSecs / CoreConstants.SECONDS_YEAR);
|
||||||
durationString += ' ' + moment.duration(eventDuration.years(), 'years').humanize();
|
let remainder = totalSecs - (years * CoreConstants.SECONDS_YEAR);
|
||||||
|
const days = Math.floor(remainder / CoreConstants.SECONDS_DAY);
|
||||||
|
|
||||||
|
remainder = totalSecs - (days * CoreConstants.SECONDS_DAY);
|
||||||
|
|
||||||
|
const hours = Math.floor(remainder / CoreConstants.SECONDS_HOUR);
|
||||||
|
remainder = remainder - (hours * CoreConstants.SECONDS_HOUR);
|
||||||
|
|
||||||
|
const mins = Math.floor(remainder / CoreConstants.SECONDS_MINUTE);
|
||||||
|
const secs = remainder - (mins * CoreConstants.SECONDS_MINUTE);
|
||||||
|
|
||||||
|
const secondsUnit = Translate.instant('core.' + (secs === 1 ? 'sec' : 'secs'));
|
||||||
|
const minutesUnit = Translate.instant('core.' + (mins === 1 ? 'min' : 'mins'));
|
||||||
|
const hoursUnit = Translate.instant('core.' + (hours === 1 ? 'hour' : 'hours'));
|
||||||
|
const daysUnit = Translate.instant('core.' + (days === 1 ? 'day' : 'days'));
|
||||||
|
const yearsUnit = Translate.instant('core.' + (years === 1 ? 'year' : 'years'));
|
||||||
|
const parts: string[] = [];
|
||||||
|
|
||||||
|
if (precision && years) {
|
||||||
|
parts.push(`${years} ${yearsUnit}`);
|
||||||
precision--;
|
precision--;
|
||||||
}
|
}
|
||||||
if (precision && eventDuration.months() > 0) {
|
if (precision && days) {
|
||||||
durationString += ' ' + moment.duration(eventDuration.months(), 'months').humanize();
|
parts.push(`${days} ${daysUnit}`);
|
||||||
precision--;
|
precision--;
|
||||||
}
|
}
|
||||||
if (precision && eventDuration.days() > 0) {
|
if (precision && hours) {
|
||||||
durationString += ' ' + moment.duration(eventDuration.days(), 'days').humanize();
|
parts.push(`${hours} ${hoursUnit}`);
|
||||||
precision--;
|
precision--;
|
||||||
}
|
}
|
||||||
if (precision && eventDuration.hours() > 0) {
|
if (precision && mins) {
|
||||||
durationString += ' ' + moment.duration(eventDuration.hours(), 'hours').humanize();
|
parts.push(`${mins} ${minutesUnit}`);
|
||||||
precision--;
|
precision--;
|
||||||
}
|
}
|
||||||
if (precision && eventDuration.minutes() > 0) {
|
if (precision && secs) {
|
||||||
durationString += ' ' + moment.duration(eventDuration.minutes(), 'minutes').humanize();
|
parts.push(`${secs} ${secondsUnit}`);
|
||||||
precision--;
|
|
||||||
}
|
|
||||||
if (precision && (eventDuration.seconds() > 0 || !durationString)) {
|
|
||||||
durationString += ' ' + moment.duration(eventDuration.seconds(), 'seconds').humanize();
|
|
||||||
precision--;
|
precision--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return durationString.trim();
|
return parts.join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue