Skip to content

Commit

Permalink
Adds warning in browsers without File System Access API
Browse files Browse the repository at this point in the history
In case any user logs in to the VSCode4Teaching web application in a browser that does not support the File System Access API (such as, for example, Firefox currently), a warning will be displayed recommending to change browser, as most of the functionality of this application will be inoperative.
  • Loading branch information
diego-guerrero committed Jun 9, 2024
1 parent 88057d3 commit 1226255
Show file tree
Hide file tree
Showing 15 changed files with 100 additions and 14 deletions.
1 change: 1 addition & 0 deletions vscode4teaching-webapp/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<app-layout-aside></app-layout-aside>
</aside>
<section [ngClass]='{"col-9": this.showAside, "col-12": !this.showAside}'>
<app-not-supported-file-system-access-api></app-not-supported-file-system-access-api>
<router-outlet></router-outlet>
</section>
</div>
Expand Down
2 changes: 2 additions & 0 deletions vscode4teaching-webapp/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { HttpRequestInterceptor } from "./services/rest-api/interceptor/http-req
import { UrlService } from "./services/url/url.service";
import { WebSocketHandler } from "./services/ws/web-socket-handler";
import { WebSocketHandlerFactory } from "./services/ws/web-socket-handler-factory.service";
import { NotSupportedFileSystemAccessApiComponent } from './components/helpers/not-supported-file-system-access-api/not-supported-file-system-access-api.component';

@NgModule({
declarations: [
Expand All @@ -42,6 +43,7 @@ import { WebSocketHandlerFactory } from "./services/ws/web-socket-handler-factor

// helpers
ProgressBarComponent,
NotSupportedFileSystemAccessApiComponent,
DelaySinceComponent,

// public
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="container justify-content-center" *ngIf="this.showFsaAPINotSupportedMessage">
<div class="row">
<div class="col mt-1 mb-3">
<div class="alert alert-v4t text-center">
<i class="fa fa-exclamation-circle"></i>&nbsp;<strong>Attention!</strong> This web browser does not support interaction with your computer files and folders, so you will not be able to use features like exercise download or automatic file synchronization.
<br>If you want to use these features, please use a compatible browser like most recent versions of Google Chrome or Microsoft Edge. Check out compatibility in <a href="https://caniuse.com/native-filesystem-api" target="_blank" class="link-v4t link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover">this link</a>.
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { NotSupportedFileSystemAccessApiComponent } from './not-supported-file-system-access-api.component';

describe('NotSupportedFileSystemAccessApiComponent', () => {
let component: NotSupportedFileSystemAccessApiComponent;
let fixture: ComponentFixture<NotSupportedFileSystemAccessApiComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [NotSupportedFileSystemAccessApiComponent]
});
fixture = TestBed.createComponent(NotSupportedFileSystemAccessApiComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Event, NavigationStart, Router } from "@angular/router";
import { supported as fileSystemAccessApiSupported } from "browser-fs-access";
import { Subscription } from "rxjs";
import { CurrentUserService } from "../../../services/auth/current-user/current-user.service";

@Component({
selector: 'app-not-supported-file-system-access-api',
templateUrl: './not-supported-file-system-access-api.component.html',
styleUrls: ['./not-supported-file-system-access-api.component.scss']
})
export class NotSupportedFileSystemAccessApiComponent implements OnInit, OnDestroy {
public showFsaAPINotSupportedMessage: boolean;
public routerSubscription?: Subscription;

constructor(private curUser: CurrentUserService, private router: Router) {
this.showFsaAPINotSupportedMessage = false;
}

async ngOnInit(): Promise<void> {
this.routerSubscription = this.router.events.subscribe({
next: async (event: Event) => {
if (event instanceof NavigationStart) {
this.showFsaAPINotSupportedMessage = !fileSystemAccessApiSupported && (await this.curUser.currentUser) !== undefined
}
}
});
}

ngOnDestroy(): void {
this.routerSubscription?.unsubscribe();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ <h3>My Courses</h3>
</div>
<div class="name">{{ course.name }}</div>
<div class="buttons">
<ng-container *ngIf="!this.curUser.isTeacher">
<ng-container *ngIf="!this.curUser.isTeacher && this.fsaApiSupported">
<a [routerLink]="['/', 'student', 'course', course.id]" class="btn btn-v4t-coloured btn-sm my-0">
<i class="fas fa-book-open"></i> Exercises
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CourseService } from "../../../../services/rest-api/model-entities/cour
import { CurrentUserService } from "../../../../services/auth/current-user/current-user.service";
import { Course } from "../../../../model/course.model";
import { User } from "../../../../model/user.model";
import { Router } from "@angular/router";
import { supported as fileSystemAccessApiSupported } from "browser-fs-access";
import { AsideService } from "../../../../services/aside/aside.service";

@Component({
Expand All @@ -17,10 +17,13 @@ export class DashboardComponent implements OnInit {

coursesLoaded: boolean;

fsaApiSupported: boolean;

constructor(private asideService: AsideService,
private courseService: CourseService,
private curUserService: CurrentUserService) {
this.coursesLoaded = false;
this.fsaApiSupported = fileSystemAccessApiSupported;
}

async ngOnInit(): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { supported as fileSystemAccessApiSupported } from "browser-fs-access";
import { ExerciseUserInfo } from "../../../../../../../model/exercise-user-info.model";
import { DirectoryNode, TreeDiffResult } from "../../../../../../../model/file-system/file-system.model";
import { SyncJobPriorityQueue } from "../../../../../../../model/file-system/syncjob-priority-queue";
Expand Down Expand Up @@ -81,7 +82,7 @@ export class AutoSyncServerComponent implements OnInit, OnDestroy {
// The current directory structure is obtained in the same way as in step 2.
// If a FileSystemDirectoryHandle already exists (in case the File System Access API can be used), it is not necessary to ask user for the directory again.
let currentDirectoryStructure: DirectoryNode | undefined;
if (this.fileSystemReadDirectoryService.fileSystemAccessAPISupported() && this.exerciseDirectoryHandle) {
if (fileSystemAccessApiSupported && this.exerciseDirectoryHandle) {
currentDirectoryStructure = await this.fileSystemReadDirectoryService.supportedFileSystemAPI(this.exerciseDirectoryHandle);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</div>
</div>
</div>
<div class="container" *ngIf="this.course">
<div class="container" *ngIf="this.course && !this.error">
<h2>{{ this.course.name }}</h2>

<ng-container *ngIf="this.courseDirectory === undefined">
Expand All @@ -23,7 +23,7 @@ <h2>{{ this.course.name }}</h2>
<ng-container *ngIf="this.courseDirectory !== undefined">
<div class="row">
<div class="col-10">
<input type="text" class="form-control" readonly [value]="courseDirectory?.name" aria-describedby="basic-addon2">
<input type="text" class="form-control" readonly [value]="courseDirectory?.name">
</div>
<div class="col-2 text-center">
<button class="btn btn-v4t" (click)="pickCourseLocalDirectory()"><i class="fas fa-folder"></i> Change directory</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ExerciseUserInfo } from "../../../../model/exercise-user-info.model";
import { Exercise } from "../../../../model/exercise.model";
import { CourseService } from "../../../../services/rest-api/model-entities/course/course.service";
import { ExerciseUserInfoService } from "../../../../services/rest-api/model-entities/exercise-user-info/exercise-user-info.service";
import { supported as fileSystemAccessApiSupported } from "browser-fs-access";

@Component({
selector: 'app-student-course',
Expand Down Expand Up @@ -32,7 +33,7 @@ export class StudentCourseComponent implements OnInit {

this.courseDirectory = undefined;

this.error = false;
this.error = !fileSystemAccessApiSupported;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ <h3>Students' progress</h3>
<ng-container *ngIf="this.isPreview">
<div class="alert alert-v4t">
<i class="fas fa-info-circle"></i> Currently, <strong>preview mode</strong> is enabled. You can only see the progress of the students.
<br>To enable the <strong>full mode</strong>, choose a directory at your local computer where the students' submissions will be synchronized on demand.
<ng-container *ngIf="this.fsaApiSupported">
<br>To enable the <strong>full mode</strong>, choose a directory at your local computer where the students' submissions will be synchronized on demand.
</ng-container>
<ng-container *ngIf="!this.fsaApiSupported">
<br><strong>Full mode is not supported</strong> in this browser. To enable it, use a browser that supports interacting with the local file system.
</ng-container>
</div>

<div class="text-center">
<button class="btn btn-v4t-coloured" (click)="pickExerciseLocalDirectory()" *ngIf="this.isPreview">
<button class="btn btn-v4t-coloured" (click)="pickExerciseLocalDirectory()" *ngIf="this.isPreview && this.fsaApiSupported">
<i class="fas fa-folder"></i>Choose directory
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { HttpEvent } from "@angular/common/http";
import { Component, Input } from '@angular/core';
import { supported as fileSystemAccessApiSupported } from "browser-fs-access";
import { Observable } from "rxjs";
import { ExerciseUserInfo } from "../../../../../../model/exercise-user-info.model";
import { Exercise } from "../../../../../../model/exercise.model";
Expand All @@ -19,6 +20,8 @@ export class StudentsProgressComponent {
// Preview mode (true) means that the user has not selected a local directory to save the files and the dashboard only shows real-time information on the progress of students
// Full mode (false) means that the user has selected a local directory to save the files and the dashboard allows them to download the files on demand
public isPreview: boolean;
// File System Access API is supported by the browser
public fsaApiSupported: boolean;
// Files last update timestamp (only for full mode)
public filesLastUpdateTimestamp: Date | undefined;
// Only one download can be active at a time (either students files, template files or solution files)
Expand All @@ -35,6 +38,7 @@ export class StudentsProgressComponent {
private fileExchangeService: FileExchangeService
) {
this.isPreview = true;
this.fsaApiSupported = fileSystemAccessApiSupported;
this.isActiveDownload = false;
this.downloadProgressBar = { visible: false, process: undefined, percentage: 0 };
this.studentIdentitiesShown = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Injectable } from '@angular/core';
import { supported } from "browser-fs-access";
import { DirectoryNode, FileNode, Node, TreeDiffResult } from "../../../model/file-system/file-system.model";
import { DirectoryNode, FileNode, Node, TreeDiffResult } from "../../../model/file-system/file-system.model";

/**
* File System service
Expand All @@ -16,10 +15,6 @@ export class FileSystemReadDirectoryService {
constructor() {
}

public fileSystemAccessAPISupported(): boolean {
return supported && window.hasOwnProperty("showDirectoryPicker");
}

/**
* Returns a DirectoryNode-based tree representing the file-and-directory structure included in directory represented by rootDirectoryHandle,
* recursively including contents of nested directories and introducing information about files.
Expand Down
10 changes: 10 additions & 0 deletions vscode4teaching-webapp/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ button.btn-xs {
}
}

a.link-v4t {
color: #F44A3E;
text-decoration-color: #F44A3E;

&:hover {
color: #F33326;
text-decoration-color: #F33326;
}
}


a.btn-v4t,
button.btn-v4t {
Expand Down

0 comments on commit 1226255

Please sign in to comment.