Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/addon/mod/forum/components/post/post.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ ion-app.app-root addon-mod-forum-post .addon-mod_forum-post {
background-color: $white;
border-bottom: 1px solid $list-md-border-color;

@include darkmode() {
background-color: $core-dark-item-bg-color;
}

.addon-forum-star {
color: $core-star-color;
}
Expand Down
2 changes: 1 addition & 1 deletion src/addon/mod/forum/pages/discussion/discussion.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ion-app.app-root page-addon-mod-forum-discussion {
.highlight .card-header .item {
background-color: $gray-lighter;
@include darkmode() {
background-color: $black;
background-color: $gray-dark;
}
}

Expand Down
54 changes: 39 additions & 15 deletions src/addon/mod/forum/pages/discussion/discussion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
import { CoreUserProvider } from '@core/user/providers/user';
import { CoreSplitViewComponent } from '@components/split-view/split-view';
import { CoreRatingProvider, CoreRatingInfo } from '@core/rating/providers/rating';
import { CoreRatingOfflineProvider } from '@core/rating/providers/offline';
Expand Down Expand Up @@ -57,7 +58,7 @@ export class AddonModForumDiscussionPage implements OnDestroy {
isOnline: boolean;
isSplitViewOn: boolean;
postHasOffline: boolean;
sort: SortType = 'flat-oldest';
sort: SortType = 'nested';
trackPosts: boolean;
replyData = {
replyingTo: 0,
Expand Down Expand Up @@ -96,19 +97,20 @@ export class AddonModForumDiscussionPage implements OnDestroy {
constructor(navParams: NavParams,
network: Network,
zone: NgZone,
private appProvider: CoreAppProvider,
private eventsProvider: CoreEventsProvider,
private sitesProvider: CoreSitesProvider,
private domUtils: CoreDomUtilsProvider,
private utils: CoreUtilsProvider,
private translate: TranslateService,
private uploaderProvider: CoreFileUploaderProvider,
private forumProvider: AddonModForumProvider,
private forumOffline: AddonModForumOfflineProvider,
private forumHelper: AddonModForumHelperProvider,
private forumSync: AddonModForumSyncProvider,
private ratingOffline: CoreRatingOfflineProvider,
@Optional() private svComponent: CoreSplitViewComponent,
protected appProvider: CoreAppProvider,
protected eventsProvider: CoreEventsProvider,
protected sitesProvider: CoreSitesProvider,
protected domUtils: CoreDomUtilsProvider,
protected utils: CoreUtilsProvider,
protected translate: TranslateService,
protected uploaderProvider: CoreFileUploaderProvider,
protected forumProvider: AddonModForumProvider,
protected forumOffline: AddonModForumOfflineProvider,
protected forumHelper: AddonModForumHelperProvider,
protected forumSync: AddonModForumSyncProvider,
protected ratingOffline: CoreRatingOfflineProvider,
protected userProvider: CoreUserProvider,
@Optional() protected svComponent: CoreSplitViewComponent,
protected navCtrl: NavController) {
this.courseId = navParams.get('courseId');
this.cmId = navParams.get('cmId');
Expand All @@ -134,7 +136,29 @@ export class AddonModForumDiscussionPage implements OnDestroy {
* View loaded.
*/
ionViewDidLoad(): void {
this.sitesProvider.getCurrentSite().getLocalSiteConfig('AddonModForumDiscussionSort', this.sort).then((value) => {
this.sitesProvider.getCurrentSite().getLocalSiteConfig('AddonModForumDiscussionSort').catch(() => {
this.userProvider.getUserPreference('forum_displaymode').catch(() => {
// Ignore errors.
}).then((value) => {
const sortValue = value && parseInt(value, 10);

switch (sortValue) {
case 1:
this.sort = 'flat-oldest';
break;
case -1:
this.sort = 'flat-newest';
break;
case 3:
this.sort = 'nested';
break;
case 2: // Threaded not implemented.
default:
// Not set, use default sort.
// @TODO add fallback to $CFG->forum_displaymode.
}
});
}).then((value) => {
this.sort = value;
}).finally(() => {
this.fetchPosts(true, false, true).then(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ <h3>{{ 'addon.mod_scorm.gradeforattempt' | translate }} {{attempt.number}}</h3>
<h3>{{ 'addon.mod_scorm.gradeforattempt' | translate }} {{attempt.number}}</h3>
<p item-content *ngIf="attempt.grade != -1">{{ attempt.grade }}</p>
<p item-content *ngIf="attempt.grade == -1">{{ 'addon.mod_scorm.cannotcalculategrade' | translate }}</p>
<p item-content *ngIf="scorm.maxattempt == 0 || attempt.number <= scorm.maxattempt">{{ 'addon.mod_scorm.offlineattemptnote' | translate }}</p>
<p item-content *ngIf="scorm.maxattempt != 0 && attempt.number > scorm.maxattempt">{{ 'addon.mod_scorm.offlineattemptovermax' | translate }}</p>
<p *ngIf="scorm.maxattempt == 0 || attempt.number <= scorm.maxattempt">{{ 'addon.mod_scorm.offlineattemptnote' | translate }}</p>
<p *ngIf="scorm.maxattempt != 0 && attempt.number > scorm.maxattempt">{{ 'addon.mod_scorm.offlineattemptovermax' | translate }}</p>
</ion-item>
<ion-item text-wrap *ngIf="scorm.displayattemptstatus && scorm.gradeMethodReadable">
<h3>{{ 'addon.mod_scorm.grademethod' | translate }}</h3>
Expand Down Expand Up @@ -95,9 +95,9 @@ <h2>{{ 'addon.mod_scorm.contents' | translate }}</h2>
<!-- If data shown doesn't belong to last attempt, show a warning. -->
<p *ngIf="attemptToContinue">{{ 'addon.mod_scorm.dataattemptshown' | translate:{number: attemptToContinue} }}</p>
<p>{{ currentOrganization.title }}</p>
<div *ngFor="let sco of toc" class="core-padding-{{sco.level}}">
<div *ngFor="let sco of toc" class="core-padding-{{sco.level}} addon-mod_scorm-type-{{sco.scormtype}}">
<p *ngIf="sco.isvisible">
<img [src]="sco.image.url" [alt]="sco.image.description" />
<core-icon [name]="sco.image.icon" [label]="sco.image.description" item-start></core-icon>
<a *ngIf="sco.prereq && sco.launch" (click)="open($event, sco.id)"><core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text></a>
<span *ngIf="!sco.prereq || !sco.launch"><core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text></span>
<span *ngIf="accessInfo && accessInfo.canviewscores && sco.score_raw">({{ 'addon.mod_scorm.score' | translate }}: {{sco.score_raw}})</span>
Expand Down
14 changes: 9 additions & 5 deletions src/addon/mod/scorm/components/index/index.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
ion-app.app-root addon-mod-scorm-index {

ion-app.app-root addon-mod-scorm-index,
ion-app.app-root page-addon-mod-scorm-toc {
.addon-mod_scorm-toc {
img {
width: auto;
display: inline;
// Hide all non sco icons using css to maintain padding.
ion-icon {
opacity: 0;
}

.addon-mod_scorm-type-sco ion-icon {
opacity: 1
}
}
}
6 changes: 3 additions & 3 deletions src/addon/mod/scorm/pages/toc/toc.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</ion-header>
<ion-content>
<nav>
<ion-list>
<ion-list class="addon-mod_scorm-toc">
<ion-item text-wrap *ngIf="attemptToContinue">
<p>{{ 'addon.mod_scorm.dataattemptshown' | translate:{number: attemptToContinue} }}</p>
</ion-item>
Expand All @@ -23,8 +23,8 @@

<!-- List of SCOs. -->
<ng-container *ngFor="let sco of toc">
<a *ngIf="sco.isvisible" ion-item text-wrap [ngClass]="'core-padding-' + sco.level" [class.core-nav-item-selected]="selected == sco.id" (click)="loadSco(sco)" [attr.disabled]="!sco.prereq || !sco.launch ? true : null" [attr.detail-none]="!sco.prereq || !sco.launch ? true : null">
<img [src]="sco.image.url" [alt]="sco.image.description" />
<a *ngIf="sco.isvisible" ion-item text-wrap [ngClass]="'core-padding-' + sco.level + ' addon-mod_scorm-type-' + sco.scormtype" [class.core-nav-item-selected]="selected == sco.id" [class]="" (click)="loadSco(sco)" [attr.disabled]="!sco.prereq || !sco.launch ? true : null" [attr.detail-none]="!sco.prereq || !sco.launch ? true : null">
<core-icon [name]="sco.image.icon" [label]="sco.image.description" item-start></core-icon>
<core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"></core-format-text>
<span *ngIf="accessInfo && accessInfo.canviewscores && sco.score_raw">({{ 'addon.mod_scorm.score' | translate }}: {{sco.score_raw}})</span>
</a>
Expand Down
2 changes: 2 additions & 0 deletions src/addon/mod/scorm/pages/toc/toc.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreDirectivesModule } from '@directives/directives.module';
import { CoreComponentsModule } from '@components/components.module';
import { AddonModScormTocPage } from './toc';

@NgModule({
Expand All @@ -24,6 +25,7 @@ import { AddonModScormTocPage } from './toc';
],
imports: [
CoreDirectivesModule,
CoreComponentsModule,
IonicPageModule.forChild(AddonModScormTocPage),
TranslateModule.forChild()
],
Expand Down
81 changes: 57 additions & 24 deletions src/addon/mod/scorm/providers/scorm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,22 @@ export class AddonModScormProvider {
'b': 'browsed',
'n': 'notattempted'
};
protected static STATUS_TO_ICON = {
assetc: 'fa-file-archive-o',
asset: 'fa-file-archive-o',
browsed: 'fa-book',
completed: 'fa-check-square-o',
failed: 'fa-times',
incomplete: 'fa-pencil-square-o',
minus: 'fa-minus',
notattempted: 'fa-square-o',
passed: 'fa-check',
plus: 'fa-plus',
popdown: 'fa-window-close-o',
popup: 'fa-window-restore',
suspend: 'fa-pause',
wait: 'fa-clock-o',
};

protected ROOT_CACHE_KEY = 'mmaModScorm:';
protected logger;
Expand Down Expand Up @@ -1048,39 +1064,56 @@ export class AddonModScormProvider {
* @param incomplete Whether the SCORM is incomplete.
* @return Image URL and description.
*/
getScoStatusIcon(sco: any, incomplete?: boolean): {url: string, description: string} {
getScoStatusIcon(sco: any, incomplete?: boolean): {icon: string, description: string} {
let imageName = '',
descName = '',
status;

if (sco.scormtype == 'sco') {
// Not an asset, calculate image using status.
status = sco.status;
if (this.VALID_STATUSES.indexOf(status) < 0) {
// Status empty or not valid, use 'notattempted'.
status = 'notattempted';
}
suspendedStr = '';

if (!incomplete) {
// Check if SCO is completed or not. If SCORM is incomplete there's no need to check SCO.
incomplete = this.isStatusIncomplete(status);
}
const status = sco.status;

if (sco.isvisible) {
if (this.VALID_STATUSES.indexOf(status) >= 0) {
if (sco.scormtype == 'sco') {
imageName = status;
descName = status;
} else {
imageName = 'asset';
descName = 'assetlaunched';
}

if (!incomplete) {
// Check if SCO is completed or not. If SCORM is incomplete there's no need to check SCO.
incomplete = this.isStatusIncomplete(status);
}

if (incomplete && sco.exitvalue == 'suspend') {
imageName = 'suspend';
descName = 'suspended';
if (incomplete && sco.exitvalue == 'suspend') {
imageName = 'suspend';
suspendedStr = ' - ' + this.translate.instant('addon.mod_scorm.suspended');
}
} else {
imageName = sco.status;
descName = sco.status;
incomplete = true;

if (sco.scormtype == 'sco') {
// Status empty or not valid, use 'notattempted'.
imageName = 'notattempted';
} else {
imageName = 'asset';
}
descName = imageName;
}
} else {
imageName = 'asset';
descName = (!sco.status || sco.status == 'notattempted') ? 'asset' : 'assetlaunched';
}

if (imageName == '') {
imageName = 'notattempted';
descName = 'notattempted';
suspendedStr = '';
}

sco.incomplete = incomplete;

return {
url: 'assets/img/scorm/' + imageName + '.gif',
description: this.translate.instant('addon.mod_scorm.' + descName)
icon: AddonModScormProvider.STATUS_TO_ICON[imageName],
description: this.translate.instant('addon.mod_scorm.' + descName) + suspendedStr
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
<div *ngIf="question.multiArray && question.multiArray.length" [attr.padding-top]="index == 1">
<h3 padding-horizontal>{{ question.text }}</h3>
<ion-grid no-padding>
<ion-row no-padding align-items-center class="hidden-phone">
<ion-col col-7>
<ion-row no-padding nowrap align-items-center class="hidden-phone">
<ion-col col-6>
<div padding>{{ 'addon.mod_survey.responses' | translate }}</div>
</ion-col>
<ion-col text-center *ngFor="let option of question.optionsArray">
Expand All @@ -56,7 +56,7 @@ <h3 padding-horizontal>{{ question.text }}</h3>
<!-- Subquestion -->
<ion-grid no-padding *ngIf="question.parent !== 0" text-wrap [class.even]="isEven">
<ion-row no-padding nowrap align-items-center radio-group [(ngModel)]="answers[question.name]" [required]="question.required">
<ion-col col-7>
<ion-col col-6>
<ion-label padding-horizontal [core-mark-required]="question.required" id="addon-mod_survey-{{question.name}}"><strong>{{question.num}}.</strong> {{ question.text }}</ion-label>
</ion-col>

Expand All @@ -77,13 +77,13 @@ <h3 padding-horizontal>{{ question.text }}</h3>
<ng-container *ngIf="(!question.multiArray || question.multiArray.length == 0) && question.parent === 0">
<ion-grid no-padding text-wrap *ngIf="question.type > 0" [class.even]="isEven">
<ion-row no-padding align-items-center>
<ion-col col-7>
<ion-col col-6>
<ion-label [core-mark-required]="question.required" padding-horizontal id="addon-mod_survey-{{question.name}}"><strong>{{question.num}}.</strong> {{ question.text }}</ion-label>
</ion-col>
<ion-col col-5>
<ion-col col-6>
<ion-select padding [(ngModel)]="answers[question.name]" [attr.aria-labelledby]="'addon-mod_survey-'+question.name" interface="action-sheet" [required]="question.required">
<ion-option *ngFor="let option of question.optionsArray; let value=index;" [value]="value">{{option}}</ion-option>
</ion-select>
<ion-option *ngFor="let option of question.optionsArray; let value=index;" [value]="value">{{option}}</ion-option>
</ion-select>
</ion-col>
</ion-row>
</ion-grid>
Expand Down
11 changes: 4 additions & 7 deletions src/addon/mod/survey/components/index/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,10 @@ export class AddonModSurveyIndexComponent extends CoreCourseModuleMainActivityCo
* @return If answers are valid
*/
isValidResponse(): boolean {
for (const x in this.answers) {
if (this.answers[x] === -1) {
return false;
}
}

return true;
return !this.questions.some((question) => {
return question.required && question.name &&
(question.type === 0 ? this.answers[question.name] == '' : parseInt(this.answers[question.name], 10) === -1);
});
}

/**
Expand Down
19 changes: 19 additions & 0 deletions src/addon/mod/wiki/components/index/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ $addon-mod-wiki-toc-title-color: $gray-darker !default;
$addon-mod-wiki-toc-border-color: $gray-dark !default;
$addon-mod-wiki-toc-background-color: $gray-light !default;

$addon-mod-wiki-dark-toc-title-color: $white !default;
$addon-mod-wiki-dark-toc-border-color: $gray-dark !default;
$addon-mod-wiki-dark-toc-background-color: $gray-darker !default;
$addon-mod-wiki-dark-newentry-link-color: $red-light !default;

ion-app.app-root addon-mod-wiki-index {
background-color: $white;
@include darkmode() {
Expand All @@ -28,6 +33,17 @@ ion-app.app-root addon-mod-wiki-index {
a {
color: $link-color;
}

@include darkmode() {
border: 1px solid $addon-mod-wiki-dark-toc-border-color;
background: $addon-mod-wiki-dark-toc-background-color;
p {
color: $core-dark-text-color !important;
}
a {
color: $core-dark-link-color;
}
}
margin: 16px;
padding: 8px;
}
Expand Down Expand Up @@ -55,6 +71,9 @@ ion-app.app-root addon-mod-wiki-index {
.wiki_newentry {
color: $addon-mod-wiki-newentry-link-color;
font-style: italic;
@include darkmode() {
color: $addon-mod-wiki-dark-newentry-link-color !important;
}
}

/* Hide edit section links */
Expand Down
4 changes: 2 additions & 2 deletions src/app/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ ion-app.app-root {
@include darkmode() {
ion-select.core-button-select,
.core-button-select {
background-color: $core-dark-item-divider-bg-color;
background-color: $core-dark-item-bg-color;


&.select-md,
Expand All @@ -509,7 +509,7 @@ ion-app.app-root {
&.button-ios,
&.select-wp,
&.button-wp {
background: $core-dark-item-divider-bg-color;
background: $core-dark-item-bg-color;
}
}
}
Expand Down
Binary file removed src/assets/img/scorm/asset.gif
Binary file not shown.
Binary file removed src/assets/img/scorm/browsed.gif
Binary file not shown.
Binary file removed src/assets/img/scorm/completed.gif
Binary file not shown.
Binary file removed src/assets/img/scorm/failed.gif
Binary file not shown.
Binary file removed src/assets/img/scorm/incomplete.gif
Binary file not shown.
Binary file removed src/assets/img/scorm/notattempted.gif
Binary file not shown.
Binary file removed src/assets/img/scorm/passed.gif
Binary file not shown.
Binary file removed src/assets/img/scorm/suspend.gif
Binary file not shown.
Loading