Skip to content

Add project images #535

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 45 commits into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a273360
Create wizard page and add logic to the wizard service
waltersajtos Apr 22, 2021
b7a6bcf
Styling images project wizzard
liekevdvoort May 10, 2021
9bae85e
Icon size fix
liekevdvoort May 10, 2021
4093a1d
Merge branch 'develop' into feature/464-add-project-images
waltersajtos Jun 5, 2021
06584c3
Add carousel
waltersajtos Jun 5, 2021
fb16c33
Update models and resources
waltersajtos Jun 5, 2021
7f01143
Fix page id's
waltersajtos Jun 5, 2021
20ba8b7
Refactor image functionality
waltersajtos Jun 5, 2021
74caa4d
Carousel image styling
waltersajtos Jun 5, 2021
6efa1ef
Fix carousel styling
waltersajtos Jun 5, 2021
a387a85
Fix styling
waltersajtos Jun 5, 2021
c6dccfc
Change functionality so the file uploader recognizes the current proj…
waltersajtos Jun 5, 2021
d9b231e
Fix linter issues
waltersajtos Jun 16, 2021
29f6473
Make sure there's always an empty spot for images
waltersajtos Jun 24, 2021
6660870
Change icon naming
waltersajtos Jun 24, 2021
4d5d676
Add loading animation to add images
waltersajtos Jun 24, 2021
52a816a
Add loading animation on edit page
waltersajtos Jun 24, 2021
8c058ca
Update changelog
waltersajtos Jun 24, 2021
cee93c4
Fix linter errors
waltersajtos Jun 24, 2021
a4db907
Merge branch 'develop' into feature/464-add-project-images
waltersajtos Jun 24, 2021
dda766a
Fixed changelog
waltersajtos Jun 24, 2021
770a998
Merge branch 'develop' into feature/464-add-project-images
waltersajtos Jun 24, 2021
96d485c
Fix edit page button loading permanently.
waltersajtos Jun 24, 2021
95040c2
Fix wizard page order
waltersajtos Jun 24, 2021
03c4be3
Aspect ratio fix
liekevdvoort Jun 24, 2021
d0db770
Add functionality for loading the images when the user clicks back in…
waltersajtos Jun 24, 2021
af2c0c3
Small dropshadow icon ledgebility
liekevdvoort Jun 24, 2021
7bf1b57
Fix linter issues
waltersajtos Jun 24, 2021
247dcb8
Merge remote-tracking branch 'origin/feature/464-add-project-images' …
waltersajtos Jun 24, 2021
604cf9c
Also on li
liekevdvoort Jun 24, 2021
db3a169
Remove duplicate overflow hidden
liekevdvoort Jun 24, 2021
ce352bb
css fix inside image carousel
liekevdvoort Jun 24, 2021
e727513
Change select color
liekevdvoort Jun 24, 2021
92e991c
Remove border around nav toggle mobile
liekevdvoort Jun 24, 2021
274ed79
Fix alignment menu item mobile menu
liekevdvoort Jun 24, 2021
7b999f9
Extra alignment fix
liekevdvoort Jun 24, 2021
672d41f
Fix slider centering and covering
liekevdvoort Jun 25, 2021
88d9d3d
Dropshadow on carousel
liekevdvoort Jun 25, 2021
9b34cfd
Reset images when wizard is completed
waltersajtos Jun 25, 2021
5855e6b
Set the file types to lowercase before checking
waltersajtos Jun 25, 2021
0711722
Update CHANGELOG.md
niraymak Jun 25, 2021
4a6ff8f
Limit amount of images that can be uploaded
waltersajtos Jun 25, 2021
44017e9
Merge branch 'develop' into feature/464-add-project-images
waltersajtos Jun 25, 2021
5317684
fix lint issue
niraymak Jun 25, 2021
2fa754e
Fix error message spam
waltersajtos Jun 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### Added

- Added project images. - [#464](https://github.com/DigitalExcellence/dex-frontend/issues/464)
- Updated selection color to improve branding - [#539](https://github.com/DigitalExcellence/dex-frontend/issues/539)
- Added bot to optimize image sizes - [#440](https://github.com/DigitalExcellence/dex-frontend/issues/540)

### Changed
Expand All @@ -33,8 +35,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- Implemented categories - [#475](https://github.com/DigitalExcellence/dex-frontend/issues/475)
- Added filter parameters to the url, so a user can share their search settings - [#493](https://github.com/DigitalExcellence/dex-frontend/issues/493)
- Added search bar inside navbar with autocomplete suggested results. - [#403](https://github.com/DigitalExcellence/dex-frontend/issues/403)
- Refactored the home page. [#380](https://github.com/DigitalExcellence/dex-frontend/issues/380)
- Added project recommendations on the home page. [#497](https://github.com/DigitalExcellence/dex-frontend/issues/497)
- Refactored the home page. - [#380](https://github.com/DigitalExcellence/dex-frontend/issues/380)
- Added project recommendations on the home page. - [#497](https://github.com/DigitalExcellence/dex-frontend/issues/497)

### Changed

Expand Down
9 changes: 9 additions & 0 deletions src/app/components/app-layout/app-layout.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@
width: 90px;
}
}
.navbar-toggler {
border: none;
}

.search-bar {
input[type="search"] {
Expand Down Expand Up @@ -165,13 +168,19 @@
display: flex;
align-items: flex-start;
margin-left: auto;
@include media-breakpoint-down(sm) {
margin-left: 0px;
}
}

.profile {
display: flex;
align-items: center;
margin-left: auto;
margin-right: 24px;
@include media-breakpoint-down(sm) {
margin-left: 0px;
}

h4 {
margin: 0 15px 0 0;
Expand Down
20 changes: 10 additions & 10 deletions src/app/components/file-uploader/file-uploader.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@
</label>
</div>
</div>
<p class="form-footnote">The recommended dimensions for an icon are atleast 512x512</p>
<p class="form-footnote">The recommended dimensions for an icon are atleast {{recommendedWidth}}x{{recommendedHeight}}</p>
<div *ngIf="showPreview" class="files-list">
<div class="single-file" *ngFor="let file of files; let i = index">
<div class="file-info">
<button type="button" class="btn btn-icon btn-danger" aria-label="error" (click)="deleteFile(i)"><span
aria-hidden="true">&times;</span>
</button>
<img alt="image-preview" class="file-icon" [src]=file?.preview>
<h4 class="file-name">
{{ file?.name }}
</h4>
<div class="single-file" *ngFor="let file of files; let i = index">
<div class="file-info">
<button type="button" class="btn btn-icon btn-danger" aria-label="error" (click)="deleteFile(i)"><span
aria-hidden="true">&times;</span>
</button>
<img alt="image-preview" class="file-icon" [src]=file?.preview>
<h4 class="file-name">
{{ file?.name }}
</h4>
<h4 class="file-size">
{{ file?.readableSize }}
</h4>
Expand Down
144 changes: 80 additions & 64 deletions src/app/components/file-uploader/file-uploader.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,23 @@ export class FileUploaderComponent {
@Input() acceptMultiple: boolean;
@Input() acceptedTypes: Array<String>;
@Input() showPreview: Boolean;

@Input() maxImages = 10;
@Input() recommendedHeight = 512;
@Input() recommendedWidth = 512;
public files: Array<UploadFile> = new Array<UploadFile>();
/**
* The maximum size of a file in bytes
*/
private maxFileSize = 2097152;

/**
* The maximum size of a file in a readable format
*/
private maxFileSizeReadable: string = this.formatBytes(this.maxFileSize, 0);

constructor(
private uploadService: FileUploaderService,
private alertService: AlertService,
private fileRetrieverService: FileRetrieverService) { }

public files: Array<UploadFile> = new Array<UploadFile>();
private uploadService: FileUploaderService,
private alertService: AlertService,
private fileRetrieverService: FileRetrieverService) { }

/**
* handle onFileDrop event
Expand All @@ -85,6 +85,65 @@ export class FileUploaderComponent {
this.fileInput.nativeElement.value = '';
}

/**
* Send the selected files to the API and return the id's
* @return Observable<Array<UploadFile>>
*/
public uploadFiles(): Observable<Array<UploadFile>> {
// Check if any files were uploaded
if (this.fileInput.nativeElement.value !== '') {
// Map all the files to an observable
const fileUploads = this.files.map(file => {
if (file.path) {
return of(file);
} else {
return this.uploadService.uploadFile(file)
.pipe(
map(event => {
switch (event.type) {
case HttpEventType.UploadProgress:
// divide the (uploaded bytes * 100) by the total bytes to calculate the progress in percentage
this.files.find(value => value.name === file.name).progress = Math.round(event.loaded * 100 / event.total);
break;
case HttpEventType.Response:
return event.body;
default:
return;
}
})
);
}
}
);
// forkJoin the observables so they can be uploaded at the same time
return forkJoin(fileUploads);
}
// If no files were updated return original list

// If there are any files left in the list
if (this.files.length) {
// Return the original list
return of(this.files);
} else {
// If there are no files in the list return undefined
return of(undefined);
}
}

/**
* Populates the fileList
* @param uploadedFiles files that have been uploaded
*/
public setFiles(uploadedFiles: Array<UploadFile>): void {
uploadedFiles.forEach(uploadedFile => {
if (uploadedFile) {
this.files.push({
...uploadedFile,
preview: this.fileRetrieverService.getIconUrl(uploadedFile)
});
}
});
}

/**
* This will finalize the data from the uploadForm and do some filetype and -size checks.
Expand All @@ -95,9 +154,22 @@ export class FileUploaderComponent {
if (!this.acceptMultiple) {
this.files = [];
}

if (this.files.length + files.length > 10) {
const alertConfig: AlertConfig = {
type: AlertType.danger,
preMessage: `You can't upload more than 10 images`,
mainMessage: `You tried to upload too many images, please remove some.`,
dismissible: true,
timeout: this.alertService.defaultTimeout
};
this.alertService.pushAlert(alertConfig);
return;
}

for (const file of files) {
if (file.size < this.maxFileSize) {
if (this.acceptedTypes.includes(file.type)) {
if (this.acceptedTypes.includes(file.type.toLocaleLowerCase())) {
this.generatePreview(file);
file.readableSize = this.formatBytes(file.size);
this.files.push(file);
Expand Down Expand Up @@ -158,60 +230,4 @@ export class FileUploaderComponent {

return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}


/**
* Send the selected files to the API and return the id's
* @return Observable<Array<UploadFile>>
*/
public uploadFiles(): Observable<Array<UploadFile>> {
// Check if any files were uploaded
if (this.fileInput.nativeElement.value !== '') {
// Map all the files to an observable
const fileUploads = this.files.map(file => this.uploadService.uploadFile(file)
.pipe(
map(event => {
switch (event.type) {
case HttpEventType.UploadProgress:
// divide the (uploaded bytes * 100) by the total bytes to calculate the progress in percentage
this.files.find(value => value.name === file.name).progress = Math.round(event.loaded * 100 / event.total);
break;
case HttpEventType.Response:
return event.body;
default:
return;
}
})
)
);
// forkJoin the observables so they can be uploaded at the same time
return forkJoin(fileUploads);
}
// If no files were updated return original list

// If there are any files left in the list
if (this.files.length) {
// Return the original list
return of(this.files);
} else {
// If there are no files in the list return undefined
return of(undefined);
}
}


/**
* Populates the fileList
* @param files files that have been uploaded
*/
public setFiles(uploadedFiles: Array<UploadFile>): void {
uploadedFiles.forEach(uploadedFile => {
if (uploadedFile) {
this.files.push({
...uploadedFile,
preview: this.fileRetrieverService.getIconUrl(uploadedFile)
});
}
});
}
}
12 changes: 7 additions & 5 deletions src/app/config/wizard-page-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface WizardPageConfig {
8: string;
9: string;
10: string;
11: string;
}

export const WizardPageConfig: WizardPageConfig = {
Expand All @@ -17,9 +18,10 @@ export const WizardPageConfig: WizardPageConfig = {
3: 'project-username',
4: 'project-name',
5: 'project-description',
6: 'project-icon',
7: 'project-collaborators',
8: 'project-call-to-action',
9: 'project-link',
10: 'project-categories'
6: 'project-images',
7: 'project-icon',
8: 'project-collaborators',
9: 'project-call-to-action',
10: 'project-link',
11: 'project-categories'
};
1 change: 1 addition & 0 deletions src/app/models/domain/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface Project {
collaborators?: Collaborator[];
callToAction?: CallToAction;
projectIcon?: UploadFile;
images?: UploadFile[];
likes?: Array<ProjectLike>;
userHasLikedProject: boolean;
likeCount: number;
Expand Down
3 changes: 2 additions & 1 deletion src/app/models/resources/project-add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface ProjectAdd {
description?: string;
uri: string;
callToAction: CallToAction;
fileId?: number;
iconId?: number;
imageIds?: number[];
categories?: ProjectCategory[];
}
3 changes: 2 additions & 1 deletion src/app/models/resources/project-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ export interface ProjectUpdate {
url: string;
callToAction: CallToAction;
categories: ProjectCategory[];
fileId?: number;
iconId?: number;
imageIds?: number[];
}
2 changes: 2 additions & 0 deletions src/app/modules/project/add/add.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { ProjectIconComponent } from './main/wizard/wizardPages/default/project-
import { ProjectNameComponent } from './main/wizard/wizardPages/default/project-name/project-name.component';
import { ProjectModule } from 'src/app/modules/project/project.module';
import { ProjectCallToActionComponent } from './main/wizard/wizardPages/default/project-call-to-action/project-call-to-action.component';
import { ProjectImagesComponent } from './main/wizard/wizardPages/default/project-images/project-images.component';
import { ProjectCategoriesComponent } from './main/wizard/wizardPages/default/project-categories/project-categories.component';

@NgModule({
Expand All @@ -45,6 +46,7 @@ import { ProjectCategoriesComponent } from './main/wizard/wizardPages/default/pr
ProjectNameComponent,
ProjectCallToActionComponent,
ProjectCategoriesComponent,
ProjectImagesComponent,

],
imports: [
Expand Down
3 changes: 3 additions & 0 deletions src/app/modules/project/add/main/wizard/wizard.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
<ng-container *ngSwitchCase="'project-description'">
<app-project-description (clickNext)="onNextStep()" [step]="(currentStep | async)"></app-project-description>
</ng-container>
<ng-container *ngSwitchCase="'project-images'">
<app-project-images (clickNext)="onNextStep()" [step]="(currentStep | async)"></app-project-images>
</ng-container>
<ng-container *ngSwitchCase="'project-icon'">
<app-project-icon (clickNext)="onNextStep()" [isOptional]="true" [step]="(currentStep | async)"></app-project-icon>
</ng-container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ export class ProjectIconComponent extends WizardStepBaseComponent implements OnI
if (this.fileUploader.files.length > 0) {
this.fileUploader.uploadFiles().subscribe(files => {
if (files[0]) {
this.wizardService.updateProject({...this.project, fileId: files[0].id});
this.wizardService.uploadFile = files[0];
this.wizardService.updateProject({...this.project, iconId: files[0].id});
this.wizardService.projectIcon = files[0];
}
super.onClickNext();
});
Expand All @@ -78,10 +78,10 @@ export class ProjectIconComponent extends WizardStepBaseComponent implements OnI
/**
* Method that determines which preview to use for the project icon
*/
getProjectIcon(): SafeUrl {
public getProjectIcon(): SafeUrl {
if (this.fileUploader?.files[0]) {
return this.fileUploader.files[0].preview;
}
return this.fileRetrieverService.getIconUrl(this.wizardService.uploadFile);
return this.fileRetrieverService.getIconUrl(this.wizardService.projectIcon);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<h2 class="step-header">{{ step.name }}</h2>
<p class="step-description">{{ step.description }}</p>
<div class="wrapper">
<div class="left">
<div class="file-preview">
<div *ngFor="let image of getProjectImages(); let i = index" [style.background-image]="'url(' + image + ')'" class="preview">
<div (click)="deleteImageClicked(i)" *ngIf="image; else noImage" class="overlay"><em class="fas fa-trash"></em></div>
<ng-template #noImage>
<div (click)="addImageClick()" class="overlay"><em class="fas fa-plus"></em></div>
</ng-template>
</div>
</div>
<div class="buttons">
<button (click)="mobileUploadButtonClick()" class="form-continue-btn grey">Upload image</button>
<button (click)="onClickNext()" class="form-continue-btn">
{{ isOptional && !(fileUploader?.files.length > 0) ? "Skip" : "Next" }}
<div class="loading-circle" *ngIf="uploadingFiles">
<em class="fas fa-circle-notch fa-pulse"></em>
</div>
</button>
</div>
</div>
<div class="project-image-picker">
<app-file-uploader
[acceptMultiple]="acceptMultiple"
[acceptedTypes]="acceptedTypes"
[showPreview]="false"
[maxImages]="10"
>

</app-file-uploader>
</div>
</div>
Loading