Skip to content

Commit

Permalink
feat(rack): upload is image
Browse files Browse the repository at this point in the history
  • Loading branch information
Polyterative committed Jan 28, 2024
1 parent 698499e commit 57abcce
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,36 @@
import { HttpClient } from '@angular/common/http';
import { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, ValidatorFn, Validators } from '@angular/forms';
import {
ChangeDetectionStrategy,
Component,
Input,
OnDestroy,
OnInit
} from '@angular/core';
import {
UntypedFormBuilder,
UntypedFormControl,
UntypedFormGroup,
ValidatorFn,
Validators
} from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
import { BehaviorSubject, concat, from, NEVER, of, Subject } from 'rxjs';
import { catchError, filter, map, startWith, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators';
import {
BehaviorSubject,
concat,
from,
NEVER,
of,
Subject
} from 'rxjs';
import {
catchError,
filter,
map,
startWith,
switchMap,
takeUntil,
withLatestFrom
} from 'rxjs/operators';
import { UserManagementService } from 'src/app/features/backbone/login/user-management.service';
import { SupabaseService } from 'src/app/features/backend/supabase.service';
import { CV } from 'src/app/models/cv';
Expand All @@ -13,6 +40,7 @@ import { FormTypes } from 'src/app/shared-interproject/components/@smart/mat-for
import { IMatFormEntityConfig } from 'src/app/shared-interproject/components/@smart/mat-form-entity/mat-form-entity.component';
import { ModuleDetailDataService } from '../module-detail-data.service';


export interface FormCV {
id: number;
name: UntypedFormControl;
Expand Down Expand Up @@ -279,6 +307,7 @@ export class ModuleEditorComponent implements OnInit, OnDestroy {
let extension: string = filename.split('.')
.pop();
let name: string = `${ this.data.name.replace(/[^a-z0-9]/gi, '_') }-${ this.data.manufacturer.name.replace(/[^a-z0-9]/gi, '_') }-${ this.panelType.control.value.name }-${ this.data.standard.name }`;

let filenameAndExtension: string = `${ name }.${ extension }`;
return this.backend.storage.uploadModulePanel(
file,
Expand Down Expand Up @@ -392,4 +421,4 @@ export class ModuleEditorComponent implements OnInit, OnDestroy {
return x;
}

}
}
122 changes: 112 additions & 10 deletions src/app/components/rack-parts/rack-detail-data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import {
} from '../../shared-interproject/dialogs/confirm-dialog/confirm-dialog.component';
import { SubManager } from '../../shared-interproject/directives/subscription-manager';
import { SharedConstants } from '../../shared-interproject/SharedConstants';
import { ModuleDetailDataService } from '../module-parts/module-detail-data.service';
import {
InputDialogComponent,
InputDialogDataInModel,
Expand All @@ -66,13 +65,9 @@ export class RackDetailDataService extends SubManager {
deleteRack$ = new Subject<RackMinimal>();
duplicateRack$ = new Subject<RackMinimal>();
renameCurrentRack$ = new Subject<void>();
// @ViewChild('screen') screen: ElementRef;
// @ViewChild('canvas') canvas: ElementRef;
downloadRackImageToUserComputer$ = new Subject<{
// screen: ElementRef,
canvas: ElementRef,
download: ElementRef
}>();
//
updateRackImage$ = new Subject<void>();
downloadRackImageToUserComputer$ = new Subject<void>();
//
currentDownloadElementRef$: BehaviorSubject<{
screen: ElementRef,
Expand Down Expand Up @@ -108,7 +103,7 @@ export class RackDetailDataService extends SubManager {
private backend: SupabaseService,
private dialog: MatDialog,
private router: Router,
private moduleDetailDataService: ModuleDetailDataService
// private moduleDetailDataService: ModuleDetailDataService
) {
super();

Expand Down Expand Up @@ -137,10 +132,117 @@ export class RackDetailDataService extends SubManager {
link.click();
link.remove();

this.snackBar.open('Image downloaded: ' + downloadName, undefined, {duration: 5000});
this.snackBar.open('Image downloaded', undefined, {duration: 5000});
}
);

// when user requests to update the preview image, upload an image to the server that will be used as a preview
this.updateRackImage$.pipe(
tap(x => this.snackBar.open('Updating image...', undefined, {duration: 4000})),
withLatestFrom(this.currentDownloadElementRef$),
// create image from HTML element using dom-to-image library
switchMap(([_, references]) => from(
domtoimage.toBlob(<any>references.screen.nativeElement, {
quality: 0.2,
bgcolor: '#ffffff',

})
)),
withLatestFrom(this.singleRackData$, this.userService.loggedUser$),
switchMap(([blob, rack, user]) => {

// convert canvas to blob
return this.backend.storage.uploadRack(
blob,
rack.id.toString() + '.jpeg'
).pipe(

);


}),
filter(x => false),
// update rack data with the new image url
// switchMap(({rack, user, filename}) => {
// // rack.imageurl = `${ user.id }/${ filename }`;
// return this.backend.update.rack(rack);
// }),
takeUntil(this.destroyEvent$),
)
.subscribe();

// when user stays still for a while in the page,upload an image to the server that will be used as a preview
// this.singleRackData$.pipe(
// filter(x => !!x),
// // the currently opened rack should be of the currently logged user
// withLatestFrom(this.userService.loggedUser$),
// filter(([rack, user]) => rack.author.id === user.id),
// // we should also make sure that we are in the rack editor page
// filter(([rack, user]) => this.router.url.includes('racks/details')),
// // wait for a while before uploading image, so that we do not upload too many images
// switchMap((data) => of(data).pipe(
// debounceTime(5000),
// // create image from HTML element using dom-to-image library
// withLatestFrom(this.currentDownloadElementRef$),
// switchMap(([data, references]) => from(
// domtoimage.toJpeg(<any>references.screen.nativeElement, {
// quality: 0.6,
// bgcolor: '#ffffff',
// })
// ).pipe(
// map(imageData => ({
// imageData,
// rack: data[0],
// user: data[1]
// }))
// )),
// // at this point, we have waited for a while, and the user has not navigated away from the rack editor page,
// // so we can upload the image to the server
// switchMap(({imageData, rack, user}) => {
//
// const filename = `${ rack.name } by ${ rack.author.username } - ${ rack.hp } HP - ${ rack.rows } rows - ${ new Date().toLocaleDateString() }`;
// // replace any characters that make use problems in the download filename
// const sanitizedFilename = filename.replace(/[/\\?%*:|"<>]/g, '-');
//
// return this.backend.storage.uploadRack(
// imageData,
// sanitizedFilename
// ).pipe(
// map(x => ({
// rack,
// user,
// filename: sanitizedFilename
// }))
// );
// }),
// // update rack data with the new image url
// switchMap(({rack, user, filename}) => {
// rack.imageurl = `${ user.id }/${ filename }`;
// return this.backend.update.rack(rack);
// }),
//
// take(1),
// // we have some events that can trigger the cancelation of the upload, so we need to keep track of them
// takeUntil(
// combineLatest([
// this.destroyEvent$,
// this.singleRackData$,
// // if user navigates away from the rack editor page, stop uploading image
// this.router.events.pipe(
// take(1),
// )
// ]
// )
// )
// )
// ),
//
// takeUntil(this.destroyEvent$),
// )
// .subscribe();

// when user requests to update the preview image, upload an image to the server that will be used as a preview


// when user toggles locked status of rack, update backend
this.requestRackEditableStatusChange$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@
<!-- create space between these-->
<div fxFlex="1 1 auto"></div>
<app-brand-primary-button
(click)="dataService.downloadRackImageToUserComputer$.next({canvas:canvasReference,download:downloadReference})"
(click)="dataService.updateRackImage$.next()"
>
Update preview
</app-brand-primary-button>
<app-brand-primary-button
(click)="dataService.downloadRackImageToUserComputer$.next()"
>
Download as image
</app-brand-primary-button>
Expand Down
17 changes: 14 additions & 3 deletions src/app/features/backend/supabase.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
User
} from '@supabase/supabase-js';
import {
delay,
forkJoin,
from,
from as rxFrom,
Expand Down Expand Up @@ -771,15 +772,25 @@ export class SupabaseService {

filenameAndExtension = this.cleanUpFileName(filenameAndExtension);

return rxFrom(
this.supabase
// if rack already has an image, delete it, then upload new image, otherwise just upload new image

const delete$ = this.supabase
.storage
.from('racks')
.remove([filenameAndExtension]);


return rxFrom(delete$).pipe(
delay(1000),
switchMap(x => this.supabase
.storage
.from('racks')
.upload('' + filenameAndExtension, file, {
cacheControl: '36000',
upsert: false,
contentType: 'image/jpeg'
})
})),
map(x => filenameAndExtension)
)
.pipe(map(x => filenameAndExtension));
},
Expand Down
6 changes: 3 additions & 3 deletions src/build.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Build information, automatically generated by `ng-info`
const build = {
version: "4.1.2",
timestamp: "Sun Jan 28 2024 13:30:37 GMT+0100 (Ora standard dell’Europa centrale)",
timestamp: "Sun Jan 28 2024 15:18:21 GMT+0100 (Ora standard dell’Europa centrale)",
message: null,
git: {
user: "Polyterative",
branch: "updates",
hash: "dd1682",
fullHash: "dd16828d0bb8c1de81e5dcde086eed571d7fce91"
hash: "0aff7a",
fullHash: "0aff7a1e1eec8d232cc28d962d3edb4b2e0a2bf2"
}
};

Expand Down

0 comments on commit 57abcce

Please sign in to comment.