Skip to content

Commit

Permalink
spaces WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
fsteff committed Nov 26, 2021
1 parent 93c5581 commit f400f00
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 23 deletions.
6 changes: 4 additions & 2 deletions filemanager-ui/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import { MatListModule} from '@angular/material/list';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import { MatFormFieldModule } from '@angular/material/form-field';
import {MatExpansionModule} from '@angular/material/expansion';
import {MatSidenavModule} from '@angular/material/sidenav';
import {MatSidenavModule} from '@angular/material/sidenav';
import {MatTooltipModule} from '@angular/material/tooltip';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
Expand Down Expand Up @@ -72,7 +73,8 @@ import { ShareOverviewComponent } from './share-overview/share-overview.componen
MatFormFieldModule,
MatProgressSpinnerModule,
MatExpansionModule,
MatSidenavModule
MatSidenavModule,
MatTooltipModule
],
providers: [],
bootstrap: [AppComponent]
Expand Down
9 changes: 5 additions & 4 deletions filemanager-ui/src/app/drive.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'
import globals from '../../../src/globals'
import { Observable, from } from 'rxjs'
import { readdirResult, FileDownload, Stat, Share } from '../../../src/EventInterfaces'
import { readdirResult, FileDownload, Stat, Share, Space } from '../../../src/EventInterfaces'
import { ActivatedRoute } from '@angular/router'

@Injectable({
Expand Down Expand Up @@ -75,13 +75,14 @@ export class DriveService {
}

async mountShare(url: string, path: string): Promise<string> {
//console.log('waiting for peers')
//const firstPeer = await globals.drive.lookupPeers(url)
//console.log('first peer: ' + firstPeer)
return globals.drive.mountShare(url, path)
}

async getFileUrl(path: string): Promise<string> {
return globals.drive.getFileUrl(path)
}

async addWriterToSpace(path: string, user: string): Promise<Space> {
return globals.drive.addWriterToSpace(path, user)
}
}
19 changes: 15 additions & 4 deletions filemanager-ui/src/app/file-list/file-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { MatDialog } from '@angular/material/dialog'
import { ActivatedRoute, Router } from '@angular/router'
import { DriveService } from '../drive.service'
import { ShareDialogComponent } from '../share-dialog/share-dialog.component'
import { Space } from '../../../../src/EventInterfaces'

export interface FileData {
name: string,
Expand All @@ -13,7 +14,8 @@ export interface FileData {
icon?: string,
size: string,
lastChanged: string,
path: string
path: string,
space?: Space
}

@Component({
Expand Down Expand Up @@ -73,14 +75,23 @@ export class FileListComponent implements OnInit, AfterViewInit {
files.map(r => {
let name = window.decodeURIComponent(r.name)
if(name.length > 64) name = name.substr(0, 32) + '...'
let icon = 'description'
if(r.stat?.isDirectory) {
if(r.space) {
icon = 'folder_shared'
} else {
icon = 'folder'
}
}
return {
name: name,
path: r.path,
isFile: r.stat?.isFile,
icon: r.stat?.isDirectory ? 'folder' : 'description',
link: r.stat?.isDirectory ? '/explorer/' + window.encodeURIComponent(r.path) : undefined,
icon: icon,
link: r.stat?.isDirectory ? '/explorer/' + window.encodeURIComponent(r.path) : undefined, // TODO: download link?
size: formatSize(r.stat?.size),
lastChanged: toDate(r.stat?.mtime)
lastChanged: toDate(r.stat?.mtime),
space: r.space
}
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,12 @@ table, .contacts-list{
mat-expansion-panel {
padding-top: 0.5em;
padding-bottom: 0.5em;
}

.icon-green {
color: #a5ca65
}

.icon-red {
color: #5c3939
}
16 changes: 11 additions & 5 deletions filemanager-ui/src/app/share-dialog/share-dialog.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,17 @@ <h1>Share</h1>
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let user">{{user.username}}</td>
</ng-container>
<ng-container matColumnDef="reserved">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let user"></td>
<ng-container matColumnDef="writer">
<th mat-header-cell *matHeaderCellDef style="text-align: right;">Write Access</th>
<td mat-cell *matCellDef="let user">
<button mat-icon-button (click)="toggleWriter(user)">
<mat-icon *ngIf="this.isWriter(user.publicUrl)" class="icon-green" matTooltip="Click to remove write access">check_circle</mat-icon>
<mat-icon *ngIf="!this.isWriter(user.publicUrl)" class="icon-red" matTooltip="Click to permit write access">cancel</mat-icon>
</button>
</td>
</ng-container>
<tr mat-row *matRowDef="let row; columns: ['icon', 'name'];"></tr>
<tr mat-row *matRowDef="let row; columns: ['icon', 'name', 'writer'];"></tr>
<tr mat-header-row *matHeaderRowDef="['icon', 'name', 'writer']"></tr>
</table>
</div>
<i *ngIf="sharedWith?.length === 0">no contacts selected</i>
Expand All @@ -41,7 +47,7 @@ <h1>Share</h1>
<td mat-cell *matCellDef="let user">{{user.username}}</td>
</ng-container>
<ng-container matColumnDef="add">
<th mat-header-cell *matHeaderCellDef></th>
<th mat-header-cell *matHeaderCellDef>Share</th>
<td mat-cell *matCellDef="let user"><button mat-icon-button (click)="onAdd(user)"><mat-icon>add_circle_outline</mat-icon></button></td>
</ng-container>
<tr mat-row *matRowDef="let row; columns: ['icon', 'name', 'add'];"></tr>
Expand Down
14 changes: 14 additions & 0 deletions filemanager-ui/src/app/share-dialog/share-dialog.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,27 @@ export class ShareDialogComponent implements OnInit {
this.allContacts = allContacts
}

isWriter(user: string) {
return this.fileData.space?.writers.includes(user)
}

onCopy() {
const input = this.urlInput.nativeElement
input.select()
document.execCommand('copy')
this.snackBarRef.open('Share URL copied to clipboard!', 'dismiss', {duration: 2000})
}

async toggleWriter(user: Contact) {
if(this.isWriter(user.publicUrl)) {
this.snackBarRef.open('Revoking write access is not implemented', 'dismiss', {duration: 2000})
} else {
this.fileData.space = await this.drive.addWriterToSpace(this.fileData.path, user.publicUrl)
console.log('converted directory ' + this.fileData.path + ' to collaboration space')
this.sharedWithTable?.renderRows()
}
}

async onAdd(user: Contact) {
await this.contacts.sendShare(user.publicUrl, this.url)
this.allContacts.splice(this.allContacts.indexOf(user), 1)
Expand Down
4 changes: 2 additions & 2 deletions src/ContactsEventHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export default class ContactsEventHandler extends MainEventHandler implements IC
const appRoot = await this.certacrypt.path('/apps/filemanager')
const view = this.certacrypt.graph.factory.get(GRAPH_VIEW)
const visited: IVertex<GraphObject>[] = []
const path = await traverse(view.query(Generator.from([new QueryState(appRoot, [], [])])), [], 0)
const path = await traverse(view.query(Generator.from([new QueryState(appRoot, [], [], view)])), [], 0)
const drivePath = path ? path.join('/') : undefined

return <Share> {shareUrl, drivePath, name: share.name, info: share.info, owner: share.owner, sharedBy: share.sharedBy, sharedWith: share.sharedWith}
Expand All @@ -136,7 +136,7 @@ export default class ContactsEventHandler extends MainEventHandler implements IC
const promises: Promise<string[]|undefined>[] = []
for(let result of results) {
if(visited.find(v => v.equals(result.vertex))) continue
const query = view.query(Generator.from([new QueryState(result.vertex, [], [])])).out(result.label)
const query = view.query(Generator.from([new QueryState(result.vertex, [], [], view)])).out(result.label)
const promise = traverse(query, path.concat([result.label]), depth + 1)
.then((found) => {
visited.push(result.vertex)
Expand Down
29 changes: 25 additions & 4 deletions src/DriveEventHandler.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { CertaCrypt, GraphObjects, Hyperdrive, createUrl, parseUrl, URL_TYPES, DriveShare } from "certacrypt";
import { CertaCrypt, GraphObjects, CryptoHyperdrive, createUrl, parseUrl, URL_TYPES, DriveShare } from "certacrypt";
import { IpcMain, dialog } from "electron";
import fs from 'fs'
import { MainEventHandler } from "./MainEventHandler";
import { IDriveEventHandler, FileDownload , Stat, readdirResult, Peer, Share} from "./EventInterfaces";
import { IDriveEventHandler, FileDownload , Stat, readdirResult, Peer, Share, Space} from "./EventInterfaces";
import unixify from 'unixify'
import { GraphObject, Vertex } from "hyper-graphdb";
import Client from '@hyperspace/client'
import { DriveGraphObject } from "certacrypt/lib/graphObjects";
import { CollaborationSpace } from "certacrypt/lib/space";

export default class DriveEventHandler extends MainEventHandler implements IDriveEventHandler{
private downloads: Array<FileDownload> = []
private static readonly appPath = '/apps/filemanager'

constructor(app: IpcMain, private drive: Hyperdrive, private certacrypt: CertaCrypt, private hyperspace: Client) {
constructor(app: IpcMain, private drive: CryptoHyperdrive, private certacrypt: CertaCrypt, private hyperspace: Client) {
super(app, 'drive')
}

static async init(app: IpcMain, certacrypt: CertaCrypt, hyperspace: Client): Promise<DriveEventHandler> {
let rootVertex = <Vertex<GraphObjects.Directory>> await certacrypt.path('/apps/filemanager')
let rootVertex = <Vertex<GraphObjects.Directory>> await certacrypt.path(this.appPath)
const drive = await certacrypt.drive(rootVertex)

const shareEdge = rootVertex.getEdges('shares')
Expand Down Expand Up @@ -151,6 +153,25 @@ export default class DriveEventHandler extends MainEventHandler implements IDriv
const filename = pathParts[pathParts.length-1]
return this.certacrypt.getFileUrl(file, filename)
}

async convertToSpace(path: string): Promise<{space: CollaborationSpace,metadata: Space}> {
await this.certacrypt.convertToCollaborationSpace(DriveEventHandler.appPath + path)
const spaceMeta = await this.drive.getSpace(path)
if(!spaceMeta?.metadata) {
throw new Error('convertToSpace: conversion failed for ' + path)
}
return spaceMeta
}
async addWriterToSpace(path: string, userUrl: string) {
let fileSpace = await this.drive.getSpace(path)
if(!fileSpace?.space) {
fileSpace = await this.convertToSpace(path)
}
const user = await this.certacrypt.getUserByUrl(userUrl)
await fileSpace.space.addWriter(user)
fileSpace.metadata.writers.push(userUrl)
return <Space> fileSpace.metadata
}
}

function filenameFromPath(path: string) {
Expand Down
8 changes: 6 additions & 2 deletions src/EventInterfaces.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ContactProfile, FriendState, GraphObjects, CommShare } from 'certacrypt'
import { ContactProfile, FriendState, GraphObjects } from 'certacrypt'
import { GraphObject } from 'hyper-graphdb';

export type Fd = number
Expand Down Expand Up @@ -37,11 +37,13 @@ export type Share = {
drivePath: string
}

export type Space = {space: string, owner: string, writers: string[], isWriteable: boolean}

export type Peer = {};

export type FileDownload = {filename: string, size: number, downloaded: number, error?: Error, localPath?: string}

export type readdirResult = { name: string, path: string, writers: string[], stat: Stat }
export type readdirResult = { name: string, path: string, space?: Space, stat: Stat }

export interface ICertaCryptEventHandler {

Expand Down Expand Up @@ -84,4 +86,6 @@ export interface IDriveEventHandler {

lookupPeers(url: string): Promise<Peer>
getFileUrl(path: string): Promise<string>

addWriterToSpace(path: string, user: string): Promise<Space>
}

0 comments on commit f400f00

Please sign in to comment.