commit
6c47098dd8
|
@ -58,6 +58,7 @@ function build_languages($languages, $keys, $added_langs = []) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_langindex_keys() {
|
function get_langindex_keys() {
|
||||||
|
$local = 0;
|
||||||
// Process the index file, just once.
|
// Process the index file, just once.
|
||||||
$keys = file_get_contents('langindex.json');
|
$keys = file_get_contents('langindex.json');
|
||||||
$keys = (array) json_decode($keys);
|
$keys = (array) json_decode($keys);
|
||||||
|
@ -67,6 +68,7 @@ function get_langindex_keys() {
|
||||||
if ($value == 'local_moodlemobileapp') {
|
if ($value == 'local_moodlemobileapp') {
|
||||||
$map->file = $value;
|
$map->file = $value;
|
||||||
$map->string = $key;
|
$map->string = $key;
|
||||||
|
$local++;
|
||||||
} else {
|
} else {
|
||||||
$exp = explode('/', $value, 2);
|
$exp = explode('/', $value, 2);
|
||||||
$map->file = $exp[0];
|
$map->file = $exp[0];
|
||||||
|
@ -87,7 +89,7 @@ function get_langindex_keys() {
|
||||||
}
|
}
|
||||||
|
|
||||||
$total = count($keys);
|
$total = count($keys);
|
||||||
echo "Total strings to translate $total\n";
|
echo "Total strings to translate $total ($local local)\n";
|
||||||
|
|
||||||
return $keys;
|
return $keys;
|
||||||
}
|
}
|
||||||
|
@ -232,6 +234,10 @@ function build_lang($lang, $keys) {
|
||||||
// Prevent double.
|
// Prevent double.
|
||||||
$text = str_replace(array('{{{', '}}}'), array('{{', '}}'), $text);
|
$text = str_replace(array('{{{', '}}}'), array('{{', '}}'), $text);
|
||||||
} else {
|
} else {
|
||||||
|
// @TODO: Remove that line when core.cannotconnect and core.login.invalidmoodleversion are completelly changed to use $a
|
||||||
|
if (($key == 'core.cannotconnect' || $key == 'core.login.invalidmoodleversion') && strpos($text, '2.4') != false) {
|
||||||
|
$text = str_replace('2.4', '{{$a}}', $text);
|
||||||
|
}
|
||||||
$local++;
|
$local++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +250,11 @@ function build_lang($lang, $keys) {
|
||||||
|
|
||||||
$success = count($translations);
|
$success = count($translations);
|
||||||
$percentage = floor($success/$total * 100);
|
$percentage = floor($success/$total * 100);
|
||||||
echo "\t\t$success of $total -> $percentage% ($local local)\n";
|
$bar = progressbar($percentage);
|
||||||
|
if (strlen($lang) <= 2 && !$parent) {
|
||||||
|
echo "\t";
|
||||||
|
}
|
||||||
|
echo "\t\t$success of $total -> $percentage% $bar ($local local)\n";
|
||||||
|
|
||||||
if ($lang == 'en') {
|
if ($lang == 'en') {
|
||||||
generate_local_moodlemobileapp($keys, $translations);
|
generate_local_moodlemobileapp($keys, $translations);
|
||||||
|
@ -254,6 +264,11 @@ function build_lang($lang, $keys) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function progressbar($percentage) {
|
||||||
|
$done = $percentage/10;
|
||||||
|
return "\t".str_repeat('=', $done) . str_repeat('-', 10-$done);
|
||||||
|
}
|
||||||
|
|
||||||
function detect_lang($lang, $keys) {
|
function detect_lang($lang, $keys) {
|
||||||
$langfoldername = get_langfolder($lang);
|
$langfoldername = get_langfolder($lang);
|
||||||
if (!$langfoldername) {
|
if (!$langfoldername) {
|
||||||
|
@ -271,12 +286,14 @@ function detect_lang($lang, $keys) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "Checking $lang";
|
$title = $lang;
|
||||||
if ($parent != "" && $parent != $lang) {
|
if ($parent != "" && $parent != $lang) {
|
||||||
echo " ($parent)";
|
$title .= " ($parent)";
|
||||||
}
|
}
|
||||||
$langname = $string['thislanguage'];
|
$langname = $string['thislanguage'];
|
||||||
echo " ".$langname." -D";
|
$title .= " ".$langname." -D";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Add the translation to the array.
|
// Add the translation to the array.
|
||||||
foreach ($keys as $key => $value) {
|
foreach ($keys as $key => $value) {
|
||||||
|
@ -300,7 +317,10 @@ function detect_lang($lang, $keys) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$percentage = floor($success/$total * 100);
|
$percentage = floor($success/$total * 100);
|
||||||
echo "\t\t$success of $total -> $percentage% ($local local)";
|
$bar = progressbar($percentage);
|
||||||
|
|
||||||
|
echo "Checking ".$title.str_repeat("\t", 7 - floor(mb_strlen($title, 'UTF-8')/8));
|
||||||
|
echo "\t$success of $total -> $percentage% $bar ($local local)";
|
||||||
if (($percentage > 75 && $local > 50) || ($percentage > 50 && $local > 75)) {
|
if (($percentage > 75 && $local > 50) || ($percentage > 50 && $local > 75)) {
|
||||||
echo " \t DETECTED\n";
|
echo " \t DETECTED\n";
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -34,7 +34,6 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo
|
||||||
component = AddonModFolderProvider.COMPONENT;
|
component = AddonModFolderProvider.COMPONENT;
|
||||||
canGetFolder: boolean;
|
canGetFolder: boolean;
|
||||||
contents: any;
|
contents: any;
|
||||||
moduleContents: any;
|
|
||||||
|
|
||||||
constructor(injector: Injector, private folderProvider: AddonModFolderProvider, private courseProvider: CoreCourseProvider,
|
constructor(injector: Injector, private folderProvider: AddonModFolderProvider, private courseProvider: CoreCourseProvider,
|
||||||
private appProvider: CoreAppProvider, private folderHelper: AddonModFolderHelperProvider) {
|
private appProvider: CoreAppProvider, private folderHelper: AddonModFolderHelperProvider) {
|
||||||
|
@ -51,7 +50,7 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo
|
||||||
|
|
||||||
if (this.path) {
|
if (this.path) {
|
||||||
// Subfolder. Use module param.
|
// Subfolder. Use module param.
|
||||||
this.showModuleData(this.module);
|
this.showModuleData(this.module, this.module.contents);
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
this.refreshIcon = 'refresh';
|
this.refreshIcon = 'refresh';
|
||||||
} else {
|
} else {
|
||||||
|
@ -81,16 +80,16 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo
|
||||||
* Convenience function to set scope data using module.
|
* Convenience function to set scope data using module.
|
||||||
* @param module Module to show.
|
* @param module Module to show.
|
||||||
*/
|
*/
|
||||||
protected showModuleData(module: any): void {
|
protected showModuleData(module: any, folderContents: any): void {
|
||||||
this.description = module.intro || module.description;
|
this.description = module.intro || module.description;
|
||||||
|
|
||||||
this.dataRetrieved.emit(module);
|
this.dataRetrieved.emit(module);
|
||||||
|
|
||||||
if (this.path) {
|
if (this.path) {
|
||||||
// Subfolder.
|
// Subfolder.
|
||||||
this.contents = this.moduleContents;
|
this.contents = folderContents;
|
||||||
} else {
|
} else {
|
||||||
this.contents = this.folderHelper.formatContents(this.moduleContents);
|
this.contents = this.folderHelper.formatContents(folderContents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,12 +100,13 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected fetchContent(refresh?: boolean): Promise<any> {
|
protected fetchContent(refresh?: boolean): Promise<any> {
|
||||||
let promise;
|
let promise,
|
||||||
|
folderContents = this.module.contents;
|
||||||
|
|
||||||
if (this.canGetFolder) {
|
if (this.canGetFolder) {
|
||||||
promise = this.folderProvider.getFolder(this.courseId, this.module.id).then((folder) => {
|
promise = this.folderProvider.getFolder(this.courseId, this.module.id).then((folder) => {
|
||||||
return this.courseProvider.loadModuleContents(this.module, this.courseId).then(() => {
|
return this.courseProvider.loadModuleContents(this.module, this.courseId).then(() => {
|
||||||
this.moduleContents = this.module.contents;
|
folderContents = this.module.contents;
|
||||||
|
|
||||||
return folder;
|
return folder;
|
||||||
});
|
});
|
||||||
|
@ -118,14 +118,14 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo
|
||||||
folder.contents = this.module.contents;
|
folder.contents = this.module.contents;
|
||||||
}
|
}
|
||||||
this.module = folder;
|
this.module = folder;
|
||||||
this.moduleContents = folder.contents;
|
folderContents = folder.contents;
|
||||||
|
|
||||||
return folder;
|
return folder;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise.then((folder) => {
|
return promise.then((folder) => {
|
||||||
this.showModuleData(folder);
|
this.showModuleData(folder, folderContents);
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.fillContextMenu(refresh);
|
this.fillContextMenu(refresh);
|
||||||
});
|
});
|
||||||
|
|
|
@ -45,11 +45,8 @@ export class AddonModForumDiscussionLinkHandler extends CoreContentLinksHandlerB
|
||||||
CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
|
CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
|
||||||
data = data || {};
|
data = data || {};
|
||||||
|
|
||||||
if (!data.instance) {
|
// On 3.6 downwards, it will open the discussion but without knowing the lock status of the discussion.
|
||||||
// Without the forumId discussions cannot be loaded (from link).
|
// However canreply will be false.
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [{
|
return [{
|
||||||
action: (siteId, navCtrl?): void => {
|
action: (siteId, navCtrl?): void => {
|
||||||
|
|
|
@ -222,12 +222,11 @@ export class AddonModResourceModuleHandler implements CoreCourseModuleHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resourceData.icon == '') {
|
|
||||||
resourceData.icon = this.courseProvider.getModuleIconSrc(this.modName, module.modicon);
|
|
||||||
}
|
|
||||||
resourceData.extra += extra.join(' ');
|
resourceData.extra += extra.join(' ');
|
||||||
} else {
|
}
|
||||||
// No files, just set the icon.
|
|
||||||
|
// No previously set, just set the icon.
|
||||||
|
if (resourceData.icon == '') {
|
||||||
resourceData.icon = this.courseProvider.getModuleIconSrc(this.modName, module.modicon);
|
resourceData.icon = this.courseProvider.getModuleIconSrc(this.modName, module.modicon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,14 @@
|
||||||
<h2 stacked text-wrap>{{ phases[workshop.phase].title }}</h2>
|
<h2 stacked text-wrap>{{ phases[workshop.phase].title }}</h2>
|
||||||
</a>
|
</a>
|
||||||
<ng-container *ngIf="phases && phases[workshop.phase] && phases[workshop.phase].tasks && phases[workshop.phase].tasks.length">
|
<ng-container *ngIf="phases && phases[workshop.phase] && phases[workshop.phase].tasks && phases[workshop.phase].tasks.length">
|
||||||
<a ion-item text-wrap *ngFor="let task of phases[workshop.phase].tasks" (click)="runTask(task)" detail-none>
|
<a ion-item text-wrap *ngFor="let task of phases[workshop.phase].tasks" [class.item-dimmed]="task.code == 'submit' && !showSubmit" (click)="runTask(task)" detail-none>
|
||||||
<ion-icon item-start name="radio-button-off" *ngIf="task.completed == null"></ion-icon>
|
<ion-icon item-start name="radio-button-off" *ngIf="task.completed == null"></ion-icon>
|
||||||
<ion-icon item-start name="close-circle" color="danger" *ngIf="task.completed == ''"></ion-icon>
|
<ion-icon item-start name="close-circle" color="danger" *ngIf="task.completed == ''"></ion-icon>
|
||||||
<ion-icon item-start name="information-circle" color="info" *ngIf="task.completed == 'info'"></ion-icon>
|
<ion-icon item-start name="information-circle" color="info" *ngIf="task.completed == 'info'"></ion-icon>
|
||||||
<ion-icon item-start name="checkmark-circle" color="success" *ngIf="task.completed == '1'"></ion-icon>
|
<ion-icon item-start name="checkmark-circle" color="success" *ngIf="task.completed == '1'"></ion-icon>
|
||||||
|
|
||||||
<h2>{{task.title}}</h2>
|
<h2>{{task.title}}</h2>
|
||||||
<p *ngIf="task.details">{{ task.details }}</p>
|
<p *ngIf="task.details" [innerHTML]="task.details"></p>
|
||||||
<ion-icon item-end *ngIf="task.link && task.code != 'submit'" name="open"></ion-icon>
|
<ion-icon item-end *ngIf="task.link && task.code != 'submit'" name="open"></ion-icon>
|
||||||
</a>
|
</a>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
|
|
||||||
<!-- Show only on current phase -->
|
<!-- Show only on current phase -->
|
||||||
<ng-container *ngIf="workshop.phase == workshopPhases.PHASE_SUBMISSION">
|
<ng-container *ngIf="workshop.phase == workshopPhases.PHASE_SUBMISSION">
|
||||||
<ion-item text-wrap *ngIf="canSubmit && ((access.creatingsubmissionallowed && !submission) || (access.modifyingsubmissionallowed && submission))">
|
<ion-item text-wrap *ngIf="showSubmit">
|
||||||
<button ion-button icon-start block *ngIf="access.creatingsubmissionallowed && !submission" (click)="gotoSubmit()">
|
<button ion-button icon-start block *ngIf="access.creatingsubmissionallowed && !submission" (click)="gotoSubmit()">
|
||||||
<ion-icon name="add"></ion-icon>
|
<ion-icon name="add"></ion-icon>
|
||||||
{{ 'addon.mod_workshop.createsubmission' | translate }}
|
{{ 'addon.mod_workshop.createsubmission' | translate }}
|
||||||
|
|
|
@ -49,6 +49,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
|
||||||
visibleGroups: false
|
visibleGroups: false
|
||||||
};
|
};
|
||||||
canSubmit = false;
|
canSubmit = false;
|
||||||
|
showSubmit = false;
|
||||||
canAssess = false;
|
canAssess = false;
|
||||||
hasNextPage = false;
|
hasNextPage = false;
|
||||||
|
|
||||||
|
@ -303,7 +304,8 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
|
||||||
const modal = this.modalCtrl.create('AddonModWorkshopPhaseInfoPage', {
|
const modal = this.modalCtrl.create('AddonModWorkshopPhaseInfoPage', {
|
||||||
phases: this.utils.objectToArray(this.phases),
|
phases: this.utils.objectToArray(this.phases),
|
||||||
workshopPhase: this.workshop.phase,
|
workshopPhase: this.workshop.phase,
|
||||||
externalUrl: this.externalUrl
|
externalUrl: this.externalUrl,
|
||||||
|
showSubmit: this.showSubmit
|
||||||
});
|
});
|
||||||
modal.onDidDismiss((goSubmit) => {
|
modal.onDidDismiss((goSubmit) => {
|
||||||
goSubmit && this.gotoSubmit();
|
goSubmit && this.gotoSubmit();
|
||||||
|
@ -338,6 +340,10 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
|
||||||
this.canSubmit = this.workshopHelper.canSubmit(this.workshop, this.access,
|
this.canSubmit = this.workshopHelper.canSubmit(this.workshop, this.access,
|
||||||
this.phases[AddonModWorkshopProvider.PHASE_SUBMISSION].tasks);
|
this.phases[AddonModWorkshopProvider.PHASE_SUBMISSION].tasks);
|
||||||
|
|
||||||
|
this.showSubmit = this.workshop.phase == AddonModWorkshopProvider.PHASE_SUBMISSION && this.canSubmit &&
|
||||||
|
((this.access.creatingsubmissionallowed && !this.submission) ||
|
||||||
|
(this.access.modifyingsubmissionallowed && this.submission));
|
||||||
|
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
if (this.canSubmit) {
|
if (this.canSubmit) {
|
||||||
|
|
|
@ -328,7 +328,8 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
const noText = this.textUtils.htmlIsBlank(inputData.content);
|
const noText = this.textUtils.htmlIsBlank(inputData.content);
|
||||||
const noFiles = !inputData.attachmentfiles.length;
|
const noFiles = !inputData.attachmentfiles.length;
|
||||||
if (this.textRequired && noText || this.fileRequired && noFiles || noText && noFiles) {
|
|
||||||
|
if ((this.textRequired && noText) || (this.fileRequired && noFiles) || (noText && noFiles)) {
|
||||||
this.domUtils.showAlertTranslated('core.notice', 'addon.mod_workshop.submissionrequiredcontent');
|
this.domUtils.showAlertTranslated('core.notice', 'addon.mod_workshop.submissionrequiredcontent');
|
||||||
|
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
{{ 'addon.mod_workshop.switchphase' + phase.code | translate }}
|
{{ 'addon.mod_workshop.switchphase' + phase.code | translate }}
|
||||||
<ion-icon item-end name="open"></ion-icon>
|
<ion-icon item-end name="open"></ion-icon>
|
||||||
</a>
|
</a>
|
||||||
<a ion-item text-wrap *ngFor="let task of phase.tasks" [class.item-dimmed]="phase.code != workshopPhase" (click)="runTask(task)" detail-none>
|
<a ion-item text-wrap *ngFor="let task of phase.tasks" [class.item-dimmed]="phase.code != workshopPhase || (task.code == 'submit' && !showSubmit)" (click)="runTask(task)" detail-none>
|
||||||
<ion-icon item-start name="radio-button-off" *ngIf="task.completed == null"></ion-icon>
|
<ion-icon item-start name="radio-button-off" *ngIf="task.completed == null"></ion-icon>
|
||||||
<ion-icon item-start name="close-circle" color="danger" *ngIf="task.completed == ''"></ion-icon>
|
<ion-icon item-start name="close-circle" color="danger" *ngIf="task.completed == ''"></ion-icon>
|
||||||
<ion-icon item-start name="information-circle" color="info" *ngIf="task.completed == 'info'"></ion-icon>
|
<ion-icon item-start name="information-circle" color="info" *ngIf="task.completed == 'info'"></ion-icon>
|
||||||
|
|
|
@ -27,10 +27,12 @@ import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
export class AddonModWorkshopPhaseInfoPage {
|
export class AddonModWorkshopPhaseInfoPage {
|
||||||
phases: any;
|
phases: any;
|
||||||
workshopPhase: number;
|
workshopPhase: number;
|
||||||
|
showSubmit: boolean;
|
||||||
|
|
||||||
constructor(params: NavParams, private viewCtrl: ViewController, private utils: CoreUtilsProvider) {
|
constructor(params: NavParams, private viewCtrl: ViewController, private utils: CoreUtilsProvider) {
|
||||||
this.phases = params.get('phases');
|
this.phases = params.get('phases');
|
||||||
this.workshopPhase = params.get('workshopPhase');
|
this.workshopPhase = params.get('workshopPhase');
|
||||||
|
this.showSubmit = params.get('showSubmit');
|
||||||
const externalUrl = params.get('externalUrl');
|
const externalUrl = params.get('externalUrl');
|
||||||
|
|
||||||
// Treat phases.
|
// Treat phases.
|
||||||
|
|
|
@ -35,6 +35,7 @@ ion-app.app-root core-ion-tabs {
|
||||||
width: $core-sidetab-size;
|
width: $core-sidetab-size;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@include border-end(0.55px, solid, rgba(0, 0, 0, 0.3));
|
||||||
.tab-button {
|
.tab-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.tab-badge.badge {
|
.tab-badge.badge {
|
||||||
|
|
|
@ -516,7 +516,7 @@ export class CoreTextUtilsProvider {
|
||||||
|
|
||||||
this.template.innerHTML = content;
|
this.template.innerHTML = content;
|
||||||
|
|
||||||
return this.template.textContent === '' && this.template.content.querySelector('img, object, hr') === null;
|
return this.template.content.textContent == '' && this.template.content.querySelector('img, object, hr') === null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue