diff --git a/BetterIServ.Backend/BetterIServ.Backend.csproj b/BetterIServ.Backend/BetterIServ.Backend.csproj
index 5f8aeea..01b1bff 100644
--- a/BetterIServ.Backend/BetterIServ.Backend.csproj
+++ b/BetterIServ.Backend/BetterIServ.Backend.csproj
@@ -10,6 +10,7 @@
+
diff --git a/BetterIServ.Backend/Controllers/HelperController.cs b/BetterIServ.Backend/Controllers/HelperController.cs
index 2fe2a62..27f70d9 100644
--- a/BetterIServ.Backend/Controllers/HelperController.cs
+++ b/BetterIServ.Backend/Controllers/HelperController.cs
@@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Mvc;
namespace BetterIServ.Backend.Controllers;
[ApiController]
-public class HelperController : Controller {
+public class HelperController : ControllerBase {
[HttpPost("/login")]
public async Task> Login([FromForm] string email, [FromForm] string password) {
@@ -34,7 +34,7 @@ public class HelperController : Controller {
return Ok(part.Replace("IServAuthSession=", ""));
}
- catch (Exception e) {
+ catch (Exception) {
return Unauthorized();
}
}
diff --git a/BetterIServ.Backend/Controllers/WebDavController.cs b/BetterIServ.Backend/Controllers/WebDavController.cs
new file mode 100644
index 0000000..ac650f1
--- /dev/null
+++ b/BetterIServ.Backend/Controllers/WebDavController.cs
@@ -0,0 +1,115 @@
+using System.Net;
+using BetterIServ.Backend.Entities;
+using Microsoft.AspNetCore.Mvc;
+using WebDav;
+
+namespace BetterIServ.Backend.Controllers;
+
+[ApiController]
+[Route("webdav")]
+public class WebDavController : ControllerBase {
+
+ [HttpPost("content")]
+ public async Task> GetDirContent([FromBody] Credentials credentials, [FromQuery] string dir) {
+ var baseAddress = new Uri($"https://webdav.{credentials.Domain}");
+ using var client = new WebDavClient(new WebDavClientParams {
+ BaseAddress = baseAddress,
+ Credentials = new NetworkCredential(credentials.Username, credentials.Password)
+ });
+
+ var result = await client.Propfind(baseAddress + dir);
+ if (!result.IsSuccessful) return NotFound(result.Description);
+
+ var contents = new List();
+ foreach (var resource in result.Resources) {
+ var name = resource.Uri.Split("/")[^1];
+ if (resource.Uri.EndsWith("/"))
+ name = resource.Uri.Split("/")[^2];
+
+ var content = new DirectoryContent {
+ Url = resource.Uri,
+ LastModified = resource.LastModifiedDate ?? DateTime.Now,
+ Size = resource.ContentLength ?? 0,
+ Type = resource.IsCollection ? "dir" : "file",
+ Name = name
+ };
+ contents.Add(content);
+ }
+ contents.RemoveAt(0);
+
+ return contents.OrderBy(item => item.Type).ToArray();
+ }
+
+ [HttpPost("download")]
+ public async Task DonwloadFile([FromBody] Credentials credentials, [FromQuery] string url) {
+ var baseAddress = new Uri($"https://webdav.{credentials.Domain}");
+ using var client = new WebDavClient(new WebDavClientParams {
+ BaseAddress = baseAddress,
+ Credentials = new NetworkCredential(credentials.Username, credentials.Password)
+ });
+
+ var file = await client.GetRawFile(new Uri(baseAddress + url));
+ if (!file.IsSuccessful) {
+ Response.StatusCode = StatusCodes.Status404NotFound;
+ return new FileStreamResult(Stream.Null, "");
+ }
+
+ var split = url.Split("/");
+ return new FileStreamResult(file.Stream, "application/octet-stream") {
+ FileDownloadName = split[^1]
+ };
+ }
+
+ [HttpPost("delete")]
+ public async Task DeleteElement([FromBody] Credentials credentials, [FromQuery] string url) {
+ var baseAddress = new Uri($"https://webdav.{credentials.Domain}");
+ using var client = new WebDavClient(new WebDavClientParams {
+ BaseAddress = baseAddress,
+ Credentials = new NetworkCredential(credentials.Username, credentials.Password)
+ });
+
+ var result = await client.Delete(new Uri(baseAddress + url));
+ if (result.IsSuccessful) return Ok();
+ return BadRequest(result.Description);
+ }
+
+ [HttpPost("upload")]
+ public async Task UploadFile([FromQuery] string url, [FromForm] string domain, [FromForm] string username, [FromForm] string password) {
+ var baseAddress = new Uri($"https://webdav.{domain}");
+ using var client = new WebDavClient(new WebDavClientParams {
+ BaseAddress = baseAddress,
+ Credentials = new NetworkCredential(username, password)
+ });
+
+ var result = await client.PutFile(new Uri(baseAddress + url), Request.Form.Files[0].OpenReadStream());
+ if (result.IsSuccessful) return Ok();
+ return BadRequest(result.Description);
+ }
+
+ [HttpPost("create")]
+ public async Task CreateFolder([FromBody] Credentials credentials, [FromQuery] string url) {
+ var baseAddress = new Uri($"https://webdav.{credentials.Domain}");
+ using var client = new WebDavClient(new WebDavClientParams {
+ BaseAddress = baseAddress,
+ Credentials = new NetworkCredential(credentials.Username, credentials.Password)
+ });
+
+ var result = await client.Mkcol(new Uri(baseAddress + url));
+ if (result.IsSuccessful) return Ok();
+ return BadRequest(result.Description);
+ }
+
+ [HttpPost("move")]
+ public async Task MoveElement([FromBody] Credentials credentials, [FromQuery] string url, [FromQuery] string newUrl) {
+ var baseAddress = new Uri($"https://webdav.{credentials.Domain}");
+ using var client = new WebDavClient(new WebDavClientParams {
+ BaseAddress = baseAddress,
+ Credentials = new NetworkCredential(credentials.Username, credentials.Password)
+ });
+
+ var result = await client.Move(new Uri(baseAddress + url), new Uri(baseAddress + newUrl));
+ if (result.IsSuccessful) return Ok();
+ return BadRequest(result.Description);
+ }
+
+}
\ No newline at end of file
diff --git a/BetterIServ.Backend/Entities/Credentials.cs b/BetterIServ.Backend/Entities/Credentials.cs
new file mode 100644
index 0000000..d8458bc
--- /dev/null
+++ b/BetterIServ.Backend/Entities/Credentials.cs
@@ -0,0 +1,7 @@
+namespace BetterIServ.Backend.Entities;
+
+public struct Credentials {
+ public string Domain { get; set; }
+ public string Username { get; set; }
+ public string Password { get; set; }
+}
\ No newline at end of file
diff --git a/BetterIServ.Backend/Entities/DirectoryContent.cs b/BetterIServ.Backend/Entities/DirectoryContent.cs
new file mode 100644
index 0000000..0f0e58e
--- /dev/null
+++ b/BetterIServ.Backend/Entities/DirectoryContent.cs
@@ -0,0 +1,9 @@
+namespace BetterIServ.Backend.Entities;
+
+public struct DirectoryContent {
+ public string Url { get; set; }
+ public string Name { get; set; }
+ public DateTime LastModified { get; set; }
+ public string Type { get; set; }
+ public long Size { get; set; }
+}
\ No newline at end of file
diff --git a/BetterIServ.Backend/Program.cs b/BetterIServ.Backend/Program.cs
index faff5c2..ee1a01c 100644
--- a/BetterIServ.Backend/Program.cs
+++ b/BetterIServ.Backend/Program.cs
@@ -20,6 +20,8 @@ if (app.Environment.IsDevelopment()) {
app.UseCors(options => {
options.WithOrigins("http://localhost:8100");
options.AllowCredentials();
+ options.AllowAnyHeader();
+ options.AllowAnyMethod();
});
app.UseAuthorization();
diff --git a/BetterIServ.Mobile/package-lock.json b/BetterIServ.Mobile/package-lock.json
index 5853361..2121232 100644
--- a/BetterIServ.Mobile/package-lock.json
+++ b/BetterIServ.Mobile/package-lock.json
@@ -14,12 +14,15 @@
"@angular/platform-browser": "^15.0.0",
"@angular/platform-browser-dynamic": "^15.0.0",
"@angular/router": "^15.0.0",
+ "@awesome-cordova-plugins/file": "^6.3.0",
"@capacitor/app": "4.1.1",
"@capacitor/core": "4.7.3",
"@capacitor/haptics": "4.1.0",
"@capacitor/keyboard": "4.1.1",
"@capacitor/status-bar": "4.1.1",
"@ionic/angular": "^7.0.0",
+ "@types/file-saver": "^2.0.5",
+ "file-saver": "^2.0.5",
"ionicons": "^7.0.0",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
@@ -692,6 +695,30 @@
"integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==",
"dev": true
},
+ "node_modules/@awesome-cordova-plugins/core": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/core/-/core-6.3.0.tgz",
+ "integrity": "sha512-MkcWO8akZLHa2RSJEPf76Y3P9wPqh5oXE8YCzn2vnYYeNyYWYnka2pHFsgUdbXJNiS+YeveUzvw+Isweg+wynA==",
+ "peer": true,
+ "dependencies": {
+ "@types/cordova": "latest"
+ },
+ "peerDependencies": {
+ "rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0"
+ }
+ },
+ "node_modules/@awesome-cordova-plugins/file": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/file/-/file-6.3.0.tgz",
+ "integrity": "sha512-w2S/X/pr0Edl8+O/ndIIlnikwkD1XEMM/8TQFp/AI1riqJFyPtYNgnU54iRjagIRJE+GRyydaUnQXp5DVn9Htg==",
+ "dependencies": {
+ "@types/cordova": "latest"
+ },
+ "peerDependencies": {
+ "@awesome-cordova-plugins/core": "^6.0.1",
+ "rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0"
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.21.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz",
@@ -3598,6 +3625,11 @@
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
"dev": true
},
+ "node_modules/@types/cordova": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.0.tgz",
+ "integrity": "sha512-AtBm1IAqqXsXszJe6XxuA2iXLhraNCj25p/FHRyikPeW0Z3YfgM6qzWb+VJglJTmZc5lqRNy84cYM/sQI5v6Vw=="
+ },
"node_modules/@types/cors": {
"version": "2.8.13",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
@@ -3656,6 +3688,11 @@
"@types/range-parser": "*"
}
},
+ "node_modules/@types/file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ=="
+ },
"node_modules/@types/fs-extra": {
"version": "8.1.2",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz",
@@ -7306,6 +7343,11 @@
"node": "^10.12.0 || >=12.0.0"
}
},
+ "node_modules/file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
+ },
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
diff --git a/BetterIServ.Mobile/package.json b/BetterIServ.Mobile/package.json
index 5be9bbc..ba798ad 100644
--- a/BetterIServ.Mobile/package.json
+++ b/BetterIServ.Mobile/package.json
@@ -20,12 +20,14 @@
"@angular/platform-browser": "^15.0.0",
"@angular/platform-browser-dynamic": "^15.0.0",
"@angular/router": "^15.0.0",
+ "@awesome-cordova-plugins/file": "^6.3.0",
"@capacitor/app": "4.1.1",
"@capacitor/core": "4.7.3",
"@capacitor/haptics": "4.1.0",
"@capacitor/keyboard": "4.1.1",
"@capacitor/status-bar": "4.1.1",
"@ionic/angular": "^7.0.0",
+ "file-saver": "^2.0.5",
"ionicons": "^7.0.0",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
@@ -46,6 +48,7 @@
"@ionic/angular-toolkit": "^9.0.0",
"@types/jasmine": "~4.0.0",
"@types/node": "^12.11.1",
+ "@types/file-saver": "^2.0.5",
"@typescript-eslint/eslint-plugin": "5.3.0",
"@typescript-eslint/parser": "5.3.0",
"eslint": "^7.6.0",
diff --git a/BetterIServ.Mobile/src/app/Api/iserv.service.ts b/BetterIServ.Mobile/src/app/api/iserv.service.ts
similarity index 95%
rename from BetterIServ.Mobile/src/app/Api/iserv.service.ts
rename to BetterIServ.Mobile/src/app/api/iserv.service.ts
index d6ba35f..69f0bfa 100644
--- a/BetterIServ.Mobile/src/app/Api/iserv.service.ts
+++ b/BetterIServ.Mobile/src/app/api/iserv.service.ts
@@ -9,7 +9,7 @@ import {firstValueFrom} from "rxjs";
export class IServService {
public userdata?: Userdata;
- private backend: string = "http://localhost:5273";
+ public backend: string = "http://localhost:5273";
constructor(private client: HttpClient) {
const data = localStorage.getItem("userdata");
diff --git a/BetterIServ.Mobile/src/app/api/webdav.service.ts b/BetterIServ.Mobile/src/app/api/webdav.service.ts
new file mode 100644
index 0000000..36d43f8
--- /dev/null
+++ b/BetterIServ.Mobile/src/app/api/webdav.service.ts
@@ -0,0 +1,52 @@
+import {Injectable} from '@angular/core';
+import {IServService} from "./iserv.service";
+import {HttpClient, HttpEvent} from "@angular/common/http";
+import {DirectoryContent} from "../entities/directoryContent";
+import {firstValueFrom, Observable} from "rxjs";
+
+@Injectable({
+ providedIn: 'root'
+})
+export class WebdavService {
+
+ constructor(private iserv: IServService, private client: HttpClient) {}
+
+ public async getDirectory(path: string): Promise {
+ const contents = await firstValueFrom(this.client.post(this.iserv.backend + "/webdav/content?dir=" + path, this.iserv.userdata));
+
+ for (let content of contents) {
+ content.name = decodeURIComponent(content.name);
+ content.url = decodeURI(content.url);
+ content.lastModified = new Date(content.lastModified);
+ }
+
+ return contents;
+ }
+
+ public downloadFile(url: string): Observable> {
+ return this.client.post(this.iserv.backend + "/webdav/download?url=" + url, this.iserv.userdata, {responseType: "blob", reportProgress: true, observe: "events"});
+ }
+
+ public async delete(url: string) {
+ await firstValueFrom(this.client.post(this.iserv.backend + "/webdav/delete?url=" + url, this.iserv.userdata));
+ }
+
+ public uploadFile(url: string, file: File): Observable> {
+ const form = new FormData();
+ form.append('username', this.iserv.userdata.username);
+ form.append('password', this.iserv.userdata.password);
+ form.append('domain', this.iserv.userdata.domain);
+ form.append('file', file);
+
+ return this.client.post(this.iserv.backend + "/webdav/upload?url=" + url, form, {reportProgress: true, observe: "events"});
+ }
+
+ public async createFolder(url: string) {
+ await firstValueFrom(this.client.post(this.iserv.backend + "/webdav/create/?url=" + url, this.iserv.userdata));
+ }
+
+ public async moveElement(url: string, newUrl: string) {
+ await firstValueFrom(this.client.post(this.iserv.backend + `/webdav/move/?url=${url}&newUrl=${newUrl}`, this.iserv.userdata));
+ }
+
+}
diff --git a/BetterIServ.Mobile/src/app/app.component.html b/BetterIServ.Mobile/src/app/app.component.html
index f39944d..1138eb0 100644
--- a/BetterIServ.Mobile/src/app/app.component.html
+++ b/BetterIServ.Mobile/src/app/app.component.html
@@ -1,6 +1,6 @@
-
+
BetterIServ
@@ -14,7 +14,7 @@
-
+
Ausloggen
diff --git a/BetterIServ.Mobile/src/app/app.component.ts b/BetterIServ.Mobile/src/app/app.component.ts
index 9b775f1..b31609b 100644
--- a/BetterIServ.Mobile/src/app/app.component.ts
+++ b/BetterIServ.Mobile/src/app/app.component.ts
@@ -2,7 +2,7 @@ import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import {Router, RouterLink, RouterLinkActive} from '@angular/router';
import { IonicModule } from '@ionic/angular';
-import {IServService} from "./Api/iserv.service";
+import {IServService} from "./api/iserv.service";
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
@@ -22,7 +22,7 @@ export class AppComponent {
];
public email = "leon.hoppe@hgbp.de";
- constructor(private router: Router, public iserv: IServService) {
+ constructor(public router: Router, public iserv: IServService) {
if (localStorage.getItem("userdata") == null) {
this.router.navigate(["login"]);
}
diff --git a/BetterIServ.Mobile/src/app/app.routes.ts b/BetterIServ.Mobile/src/app/app.routes.ts
index 4ef11e2..bca29f3 100644
--- a/BetterIServ.Mobile/src/app/app.routes.ts
+++ b/BetterIServ.Mobile/src/app/app.routes.ts
@@ -8,10 +8,14 @@ export const routes: Routes = [
},
{
path: 'home',
- loadComponent: () => import('./home/home.page').then( m => m.HomePage)
+ loadComponent: () => import('./pages/home/home.page').then(m => m.HomePage)
},
{
path: 'login',
- loadComponent: () => import('./login/login.page').then( m => m.LoginPage)
+ loadComponent: () => import('./pages/login/login.page').then(m => m.LoginPage)
+ },
+ {
+ path: 'files',
+ loadComponent: () => import('./pages/files/files.page').then( m => m.FilesPage)
},
];
diff --git a/BetterIServ.Mobile/src/app/entities/directoryContent.ts b/BetterIServ.Mobile/src/app/entities/directoryContent.ts
new file mode 100644
index 0000000..b6b4f21
--- /dev/null
+++ b/BetterIServ.Mobile/src/app/entities/directoryContent.ts
@@ -0,0 +1,7 @@
+export interface DirectoryContent {
+ url: string,
+ name: string,
+ lastModified: Date,
+ type: string,
+ size: number
+}
diff --git a/BetterIServ.Mobile/src/app/home/home.page.scss b/BetterIServ.Mobile/src/app/home/home.page.scss
deleted file mode 100644
index cceaa75..0000000
--- a/BetterIServ.Mobile/src/app/home/home.page.scss
+++ /dev/null
@@ -1,28 +0,0 @@
-ion-menu-button {
- color: var(--ion-color-primary);
-}
-
-#container {
- text-align: center;
- position: absolute;
- left: 0;
- right: 0;
- top: 50%;
- transform: translateY(-50%);
-}
-
-#container strong {
- font-size: 20px;
- line-height: 26px;
-}
-
-#container p {
- font-size: 16px;
- line-height: 22px;
- color: #8c8c8c;
- margin: 0;
-}
-
-#container a {
- text-decoration: none;
-}
diff --git a/BetterIServ.Mobile/src/app/pages/files/files.page.html b/BetterIServ.Mobile/src/app/pages/files/files.page.html
new file mode 100644
index 0000000..27a0bb8
--- /dev/null
+++ b/BetterIServ.Mobile/src/app/pages/files/files.page.html
@@ -0,0 +1,95 @@
+
+
+
+
+
+ Dateien
+
+
+
+
+
+
+
+
+ Dateien
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Abbrechen
+
+ Neuer Ordner
+
+ Erstellen
+
+
+
+
+
+ Name
+
+
+
+
+
+
+
+ Verschieben
+
+
+
+
+
+
+ {{currentDirectory}}
+
+
+
+ Übergeordnetes Verzeichnis
+
+
+
+
+ {{item.name}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Eigene
+
+
+
+
+
+ Gruppen
+
+
+
+
+
+
diff --git a/BetterIServ.Mobile/src/app/pages/files/files.page.scss b/BetterIServ.Mobile/src/app/pages/files/files.page.scss
new file mode 100644
index 0000000..ed5dd56
--- /dev/null
+++ b/BetterIServ.Mobile/src/app/pages/files/files.page.scss
@@ -0,0 +1,8 @@
+ion-label {
+ margin-left: 10px;
+ cursor: pointer;
+}
+
+.active {
+ color: var(--ion-color-primary);
+}
diff --git a/BetterIServ.Mobile/src/app/pages/files/files.page.ts b/BetterIServ.Mobile/src/app/pages/files/files.page.ts
new file mode 100644
index 0000000..62ba3c8
--- /dev/null
+++ b/BetterIServ.Mobile/src/app/pages/files/files.page.ts
@@ -0,0 +1,173 @@
+import {Component, OnInit} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {FormsModule} from '@angular/forms';
+import {ActionSheetController, AlertController, IonicModule, Platform} from '@ionic/angular';
+import {WebdavService} from "../../api/webdav.service";
+import {DirectoryContent} from "../../entities/directoryContent";
+import {File} from "@awesome-cordova-plugins/file/ngx";
+import {saveAs} from "file-saver";
+import {HttpDownloadProgressEvent, HttpEventType} from "@angular/common/http";
+
+@Component({
+ selector: 'app-files',
+ templateUrl: './files.page.html',
+ styleUrls: ['./files.page.scss'],
+ standalone: true,
+ imports: [IonicModule, CommonModule, FormsModule]
+})
+export class FilesPage implements OnInit {
+
+ public currentDirectory: string = "/Files/";
+ public directoryContent: DirectoryContent[];
+ public clipboard: DirectoryContent = undefined;
+ public loading: boolean = true;
+
+ public progress: number = -1;
+
+ constructor(private webdav: WebdavService, private platform: Platform, private menus: ActionSheetController, private alerts: AlertController) { }
+
+ async ngOnInit() {
+ this.directoryContent = await this.webdav.getDirectory(this.currentDirectory);
+ this.loading = false;
+ }
+
+ public async switchDirectory(dir: string) {
+ this.loading = true;
+ this.directoryContent = await this.webdav.getDirectory(dir);
+ this.currentDirectory = dir;
+ this.loading = false;
+ }
+
+ public async goUpFolder() {
+ const split = this.currentDirectory.split("/");
+ await this.switchDirectory(this.currentDirectory.replace(split[split.length - 2] + "/", ""));
+ }
+
+ public async interact(item: DirectoryContent) {
+ if (item.type == "dir") {
+ await this.switchDirectory(item.url);
+ }else {
+ this.webdav.downloadFile(item.url).subscribe(async event => {
+ if (event.type == HttpEventType.DownloadProgress) {
+ const e = event as HttpDownloadProgressEvent;
+ this.progress = e.loaded / e.total * 100;
+ }
+
+ if (event.type == HttpEventType.Response) {
+ const blob = event.body;
+ const file = new File();
+
+ if (this.platform.is('desktop')) {
+ saveAs(blob, item.name);
+ this.progress = -1;
+ return;
+ }
+
+ const downloadPath = (
+ this.platform.is('android')
+ ) ? file.externalDataDirectory : file.documentsDirectory;
+ await file.writeFile(downloadPath, item.name, blob, {replace: true});
+ this.progress = -1;
+ }
+ })
+ }
+ }
+
+ public async openMenu(item: DirectoryContent) {
+ const menu = await this.menus.create({
+ header: item.name,
+ buttons: [
+ {
+ text: "Löschen",
+ role: "destructive",
+ data: {action: "delete"}
+ },
+ {
+ text: "Verschieben",
+ data: {action: "move"}
+ },
+ {
+ text: "Abbrechen",
+ role: "cancel",
+ data: {action: "cancel"}
+ }
+ ]
+ });
+
+ await menu.present();
+ const result = await menu.onDidDismiss<{action: string}>();
+
+ if (result.data?.action == undefined) return;
+ if (result.data.action == "delete") {
+ const alert = await this.alerts.create({
+ subHeader: "Möchtest du dieses Element wirklich löschen?",
+ message: item.name,
+ buttons: [
+ {
+ text: "Abbrechen",
+ role: "cancel"
+ },
+ {
+ text: "Löschen",
+ role: "destructive"
+ },
+ ]
+ });
+
+ await alert.present();
+ const result = await alert.onDidDismiss();
+ if (result.role == "destructive") {
+ this.loading = true;
+ await this.webdav.delete(item.url);
+ await this.switchDirectory(this.currentDirectory);
+ this.loading = false;
+
+ await (await this.alerts.create({
+ header: "Element gelöscht!",
+ buttons: ["Ok"]
+ })).present();
+ }
+ }
+ if (result.data.action == "move") {
+ this.clipboard = item;
+ }
+ }
+
+ public async onUpload(files: FileList, form: HTMLFormElement) {
+ this.loading = true;
+ const uploads: Promise[] = [];
+
+ for (let i = 0; i < files.length; i++) {
+ const file = files.item(i);
+ uploads.push(new Promise(resolve => {
+ this.webdav.uploadFile(this.currentDirectory + file.name, file).subscribe(event => {
+ if (event.type == HttpEventType.Response) {
+ resolve();
+ }
+ });
+ }))
+ }
+
+ await Promise.all(uploads);
+ await this.switchDirectory(this.currentDirectory);
+ this.loading = false;
+ form.reset();
+ }
+
+ public async createFolder(event: any) {
+ if (event.detail.data == null) return;
+ this.loading = true;
+ await this.webdav.createFolder(this.currentDirectory + event.detail.data);
+ await this.switchDirectory(this.currentDirectory);
+ this.loading = false;
+ }
+
+ public async onMove() {
+ this.loading = true;
+ await this.webdav.moveElement(this.clipboard.url, this.currentDirectory + this.clipboard.name);
+ await this.switchDirectory(this.currentDirectory);
+ this.loading = false;
+ delete this.clipboard;
+ }
+
+}
diff --git a/BetterIServ.Mobile/src/app/home/home.page.html b/BetterIServ.Mobile/src/app/pages/home/home.page.html
similarity index 65%
rename from BetterIServ.Mobile/src/app/home/home.page.html
rename to BetterIServ.Mobile/src/app/pages/home/home.page.html
index 2efad0c..f8ab9d5 100644
--- a/BetterIServ.Mobile/src/app/home/home.page.html
+++ b/BetterIServ.Mobile/src/app/pages/home/home.page.html
@@ -13,9 +13,4 @@
Übersicht
-
-
diff --git a/BetterIServ.Mobile/src/app/pages/home/home.page.scss b/BetterIServ.Mobile/src/app/pages/home/home.page.scss
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/BetterIServ.Mobile/src/app/pages/home/home.page.scss
@@ -0,0 +1 @@
+
diff --git a/BetterIServ.Mobile/src/app/home/home.page.ts b/BetterIServ.Mobile/src/app/pages/home/home.page.ts
similarity index 100%
rename from BetterIServ.Mobile/src/app/home/home.page.ts
rename to BetterIServ.Mobile/src/app/pages/home/home.page.ts
diff --git a/BetterIServ.Mobile/src/app/login/login.page.html b/BetterIServ.Mobile/src/app/pages/login/login.page.html
similarity index 100%
rename from BetterIServ.Mobile/src/app/login/login.page.html
rename to BetterIServ.Mobile/src/app/pages/login/login.page.html
diff --git a/BetterIServ.Mobile/src/app/login/login.page.scss b/BetterIServ.Mobile/src/app/pages/login/login.page.scss
similarity index 100%
rename from BetterIServ.Mobile/src/app/login/login.page.scss
rename to BetterIServ.Mobile/src/app/pages/login/login.page.scss
diff --git a/BetterIServ.Mobile/src/app/login/login.page.ts b/BetterIServ.Mobile/src/app/pages/login/login.page.ts
similarity index 95%
rename from BetterIServ.Mobile/src/app/login/login.page.ts
rename to BetterIServ.Mobile/src/app/pages/login/login.page.ts
index c59ae75..7178846 100644
--- a/BetterIServ.Mobile/src/app/login/login.page.ts
+++ b/BetterIServ.Mobile/src/app/pages/login/login.page.ts
@@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {AlertController, IonicModule} from '@ionic/angular';
-import {IServService} from "../Api/iserv.service";
+import {IServService} from "../../api/iserv.service";
import {Router} from "@angular/router";
@Component({
diff --git a/BetterIServ.Mobile/src/global.scss b/BetterIServ.Mobile/src/global.scss
index d89e39b..ba50f1f 100644
--- a/BetterIServ.Mobile/src/global.scss
+++ b/BetterIServ.Mobile/src/global.scss
@@ -24,3 +24,7 @@
@import "@ionic/angular/css/text-alignment.css";
@import "@ionic/angular/css/text-transformation.css";
@import "@ionic/angular/css/flex-utils.css";
+
+ion-menu-button {
+ color: var(--ion-color-primary);
+}
diff --git a/BetterIServ.Mobile/tsconfig.json b/BetterIServ.Mobile/tsconfig.json
index 6d869b4..1168f6e 100644
--- a/BetterIServ.Mobile/tsconfig.json
+++ b/BetterIServ.Mobile/tsconfig.json
@@ -5,7 +5,7 @@
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
- "strict": true,
+ "strict": false,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,