Skip to content

Commit

Permalink
feat(rack): download is image
Browse files Browse the repository at this point in the history
  • Loading branch information
Polyterative committed Jan 28, 2024
1 parent dd16828 commit 698499e
Show file tree
Hide file tree
Showing 13 changed files with 800 additions and 759 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"graphology-layout-force": "^0.2.4",
"graphology-layout-forceatlas2": "^0.8.2",
"graphology-types": "^0.24.3",
"dom-to-image": "^2.6.0",
"lodash": "^4.17.21",
"lottie-web": "^5.9.1",
"luxon": "^2.3.1",
Expand Down Expand Up @@ -85,6 +86,7 @@
"@types/lodash": "^4.14.182",
"@types/luxon": "^2.3.2",
"@types/node": "^18.0.1",
"@types/dom-to-image": "^2.6.0",
"angular-build-info": "^2.0.1",
"copyfiles": "^2.4.1",
"jasmine-core": "^4.0.1",
Expand All @@ -100,4 +102,4 @@
"ts-node": "^10.7.0",
"typescript": "4.7.4"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import {
ChangeDetectionStrategy,
Component,
Input,
OnInit
} from '@angular/core';
import {
Observable,
Subject
} from 'rxjs';
import {
map,
takeUntil
} from 'rxjs/operators';
import { UserManagementService } from 'src/app/features/backbone/login/user-management.service';
import { MinimalModule } from 'src/app/models/module';
import { RackDetailDataService } from '../../rack-parts/rack-detail-data.service';
import { ModuleDetailDataService } from '../module-detail-data.service';


@Component({
selector: 'app-module-minimal',
templateUrl: './module-minimal.component.html',
Expand Down Expand Up @@ -65,4 +77,4 @@ export const defaultModuleMinimalViewConfig: ModuleMinimalViewConfig = {
hidePanelsOptions: true,
bigPanelImage: false,
ellipseDescription: true
};
};
49 changes: 49 additions & 0 deletions src/app/components/rack-parts/rack-detail-data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import _ from 'lodash';
import {
BehaviorSubject,
combineLatest,
from,
of,
ReplaySubject,
Subject
Expand Down Expand Up @@ -55,6 +56,7 @@ import {
Validators
} from "@angular/forms";
import { FormTypes } from "../../shared-interproject/components/@smart/mat-form-entity/form-element-models";
import domtoimage from 'dom-to-image';


@Injectable()
Expand All @@ -64,6 +66,20 @@ 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
}>();
//
currentDownloadElementRef$: BehaviorSubject<{
screen: ElementRef,
} | undefined> = new BehaviorSubject<{
screen: ElementRef,
}>(undefined);

addModuleToRack$ = new Subject<MinimalModule>();
shouldShowPanelImages$ = new BehaviorSubject<boolean>(true);

Expand All @@ -82,6 +98,7 @@ export class RackDetailDataService extends SubManager {
requestRackedModuleRemoval$ = new Subject<RackedModule>();
requestRackedModuleDuplication$ = new Subject<RackedModule>();
requestRackedModulesDbSync$ = new Subject<void>();
//

protected destroyEvent$ = new Subject<void>();

Expand All @@ -95,6 +112,36 @@ export class RackDetailDataService extends SubManager {
) {
super();

// when user requests to download rack image, download it using HTML2Canvas
this.downloadRackImageToUserComputer$.pipe(
tap(x => this.snackBar.open('Downloading image...', undefined, {duration: 4000})),
withLatestFrom(this.currentDownloadElementRef$),
switchMap(([_, references]) => from(
domtoimage.toJpeg(<any>references.screen.nativeElement, {
quality: 0.9,
bgcolor: '#ffffff',
})
)),
withLatestFrom(this.singleRackData$),
takeUntil(this.destroyEvent$)
)
.subscribe(
([imageData, rackData]) => {

const link = document.createElement('a');
let downloadName = `${ rackData.name } by ${ rackData.author.username } - ${ rackData.hp } HP - ${ rackData.rows } rows - ${ new Date().toLocaleDateString() }`;
link.download = `${ downloadName }.jpeg`;
// replace any characters that make use problems in the download filename
link.download = link.download.replace(/[/\\?%*:|"<>]/g, '-');
link.href = imageData;
link.click();
link.remove();

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


// when user toggles locked status of rack, update backend
this.requestRackEditableStatusChange$
.pipe(
Expand Down Expand Up @@ -579,4 +626,6 @@ export class RackDetailDataService extends SubManager {
}
this.updateModulesColumnIds(rackedModules, deepCopiedRackedModule.rackingData.row);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,17 @@
'editiableBG':bag.isCurrentRackPropertyOfCurrentUser&&bag.isCurrentRackEditable,
'readOnlyBG':(bag.isCurrentRackPropertyOfCurrentUser&&(!bag.isCurrentRackEditable))
}"

>
<div class="col gap1 transition-all scroll custom-scrollbar"
[ngClass]="{'rackLocked':!(bag.isCurrentRackPropertyOfCurrentUser&&bag.isCurrentRackEditable)}"

>
<lib-screen-wrapper [maxSize]="data.hp+'rem'"

>
<div class="col gap1"

>
<div class="row gap1">
<mat-slide-toggle [checked]="dataService.shouldShowPanelImages$|async"
Expand All @@ -47,7 +48,17 @@
>
I've got many modules
</mat-slide-toggle>

<!-- create space between these-->
<div fxFlex="1 1 auto"></div>
<app-brand-primary-button
(click)="dataService.downloadRackImageToUserComputer$.next({canvas:canvasReference,download:downloadReference})"
>
Download as image
</app-brand-primary-button>
</div>


<app-rack-visual-model [rackData]="data"
[rowedRackedModules]="bag.rowedRackedModules"
[isCurrentRackPropertyOfCurrentUser]="bag.isCurrentRackPropertyOfCurrentUser"
Expand Down Expand Up @@ -78,3 +89,9 @@
</ng-template>

</ng-container>


<div id="download">
<img #canvas>
<a #download></a>
</div>
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
$bgOpacity: 0.8;
$bgOpacity: 0.8;
$bgGradientBG: rgb(223, 223, 223);

.readOnlyBG {
//background: $bgGradientBG;
background: $bgGradientBG;
background: $bgGradientBG;
background-color: transparentize(rgb(0, 0, 0, 0), $bgOpacity);
}

.editiableBG {
//background: $bgGradientBG;
background: $bgGradientBG;
background: $bgGradientBG;
background-color: transparentize(rgb(53, 178, 74), $bgOpacity);
}

Expand All @@ -19,4 +19,4 @@ $bgGradientBG: rgb(223, 223, 223);

.smallerScale {
transform: scale(0.75);
}
}
37 changes: 27 additions & 10 deletions src/app/components/rack-parts/rack-editor/rack-editor.component.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
import {ChangeDetectionStrategy, Component, Input, OnInit} from '@angular/core';
import {MatSnackBar} from '@angular/material/snack-bar';
import {Subject} from 'rxjs';
import {filter, takeUntil, withLatestFrom} from 'rxjs/operators';
import {RackDetailDataService} from 'src/app/components/rack-parts/rack-detail-data.service';
import {SupabaseService} from 'src/app/features/backend/supabase.service';
import {RackedModule} from 'src/app/models/module';
import {RackMinimal} from 'src/app/models/rack';
import {
ChangeDetectionStrategy,
Component,
ElementRef,
Input,
OnInit,
ViewChild
} from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Subject } from 'rxjs';
import {
filter,
takeUntil,
withLatestFrom
} from 'rxjs/operators';
import { RackDetailDataService } from 'src/app/components/rack-parts/rack-detail-data.service';
import { SupabaseService } from 'src/app/features/backend/supabase.service';
import { RackedModule } from 'src/app/models/module';
import { RackMinimal } from 'src/app/models/rack';
import {
ContextMenuItem,
GeneralContextMenuDataService
} from 'src/app/shared-interproject/components/@smart/general-context-menu/general-context-menu-data.service';
import {SubManager} from 'src/app/shared-interproject/directives/subscription-manager';
import { SubManager } from 'src/app/shared-interproject/directives/subscription-manager';
import {
defaultModuleMinimalViewConfig,
ModuleMinimalViewConfig
} from '../../module-parts/module-minimal/module-minimal.component';


export interface ModuleRightClick {
$event: MouseEvent;
rackedModule: RackedModule;
Expand Down Expand Up @@ -43,7 +55,12 @@ export class RackEditorComponent extends SubManager implements OnInit {
hideDates: true,
hideTags: true
};
//
@ViewChild('screen') screenReference: ElementRef;
@ViewChild('canvas') canvasReference: ElementRef;
@ViewChild('download') downloadReference: ElementRef;

//
constructor(
public snackBar: MatSnackBar,
public backend: SupabaseService,
Expand Down Expand Up @@ -151,4 +168,4 @@ export class RackEditorComponent extends SubManager implements OnInit {

}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class="widthRuler"
>{{rackData.hp}}</mat-card-subtitle>

<div class="col gap0 ">
<div class="col gap0 " #screen id="screen">
<ng-container *ngFor="let row of rowedRackedModules; index as rowId"
>
<div class="row"
Expand All @@ -30,6 +30,9 @@

</div>
</ng-container>
<!-- small watermark,in style of powered by patcher.xyz on center-->
<div class="watermark" fxLayoutAlign="center center">Planned on patcher.xyz</div>

</div>
<div fxFlex="100"></div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@

.cdk-drop-list-dragging .module:not(.cdk-drag-placeholder) {
background-color: #E33636 !important;
transition: transform 150ms cubic-bezier(0, 0, 0.2, 1);
transition: transform 150ms cubic-bezier(0, 0, 0.2, 1);
}

.widthRuler {
border-width: .1rem;
border-color: rgba(0, 0, 0, 0.3);
border-top-style: solid;
border-width: .1rem;
border-color: rgba(0, 0, 0, 0.3);
border-top-style: solid;
border-right-style: solid;
border-left-style: solid;
border-left-style: solid;

padding: 0.5em;
padding: 0.5em;
}

.innerEditor {
Expand All @@ -36,12 +36,20 @@
.row-bg {
@include mat.elevation(2);

$gridColor: rgba(0, 0, 0, 0.15);
$gridWeight: .1rem;
$gridColor: rgba(0, 0, 0, 0.15);
$gridWeight: .1rem;

background-color: rgba(255, 255, 255, 0.25);
background-image: linear-gradient(to right, $gridColor $gridWeight, transparent $gridWeight);
background-size: 1rem;
min-height: 4rem;
min-width: 4rem;
background-size: 1rem;
min-height: 4rem;
min-width: 4rem;
}

.watermark {

opacity: 0.75;
padding: 1rem;
// center
//transform: translate(-50%, -50%);
}
Loading

0 comments on commit 698499e

Please sign in to comment.