Add file upload functionality with dialog components and update image handling
This commit is contained in:
+4
-36
@@ -1,33 +1,23 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA, Inject, inject, Renderer2} from '@angular/core';
|
||||
import {AsyncPipe, DOCUMENT, NgOptimizedImage} from "@angular/common";
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA, inject} from '@angular/core';
|
||||
import {AsyncPipe} from "@angular/common";
|
||||
import {FormsModule} from "@angular/forms";
|
||||
import {MatButton, MatMiniFabButton} from "@angular/material/button";
|
||||
import {
|
||||
MatCard,
|
||||
MatCardActions,
|
||||
MatCardContent,
|
||||
MatCardHeader,
|
||||
MatCardImage,
|
||||
MatCardXlImage
|
||||
MatCardHeader
|
||||
} from "@angular/material/card";
|
||||
import {MatFormField, MatInput, MatLabel} from "@angular/material/input";
|
||||
import {Image} from '../../../models/image';
|
||||
import {ZhipuaiImageService} from '../zhipuai-image.service';
|
||||
import {SpinnerService} from '../../../services/spinner.service';
|
||||
import {MatProgressSpinner} from '@angular/material/progress-spinner';
|
||||
|
||||
import {FileUploadService} from '../../../services/file-upload-api.service';
|
||||
import {Observable, Subscription} from 'rxjs';
|
||||
import {HttpClient, HttpResponse} from '@angular/common/http';
|
||||
import {MatToolbar, MatToolbarRow} from '@angular/material/toolbar';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {MatTooltip} from '@angular/material/tooltip';
|
||||
import {AuthService} from '../../../services/auth.service';
|
||||
import {TokenStorageService} from '../../../services/token-storage.service';
|
||||
import {FileInfo} from '../../../models/file-info';
|
||||
import {UserApiService} from '../../user-module/user-api.service';
|
||||
import {MatProgressBar} from '@angular/material/progress-bar';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-generate-image.component',
|
||||
@@ -43,26 +33,17 @@ import {MatProgressBar} from '@angular/material/progress-bar';
|
||||
MatInput,
|
||||
MatLabel,
|
||||
MatProgressSpinner,
|
||||
NgOptimizedImage,
|
||||
MatCardXlImage,
|
||||
MatCardImage,
|
||||
MatToolbarRow,
|
||||
MatToolbar,
|
||||
MatIcon,
|
||||
MatMiniFabButton,
|
||||
MatTooltip,
|
||||
MatProgressBar
|
||||
|
||||
|
||||
],
|
||||
templateUrl: './generate-image.component.html',
|
||||
styleUrl: './generate-image.component.scss',
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class GenerateImageComponent {
|
||||
|
||||
isSpinnerVisible = false;
|
||||
|
||||
query : string = '';
|
||||
|
||||
images: Image[] = [];
|
||||
@@ -70,10 +51,6 @@ export class GenerateImageComponent {
|
||||
url: ''
|
||||
};
|
||||
|
||||
currentFile?: File;
|
||||
message = '';
|
||||
|
||||
|
||||
isLoggedIn = false;
|
||||
|
||||
private storageService: TokenStorageService = inject(TokenStorageService);
|
||||
@@ -81,13 +58,8 @@ export class GenerateImageComponent {
|
||||
constructor(
|
||||
private zhipuaiImageService: ZhipuaiImageService,
|
||||
public spinnerService: SpinnerService,
|
||||
private uploadService: FileUploadService,
|
||||
private userApiService:UserApiService,
|
||||
|
||||
|
||||
private userApiService:UserApiService
|
||||
) {
|
||||
|
||||
|
||||
this.isLoggedIn = this.storageService.isLoggedIn();
|
||||
}
|
||||
|
||||
@@ -108,7 +80,6 @@ export class GenerateImageComponent {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
save(url: string | undefined) {
|
||||
let requestUrl:string = url?url:"";
|
||||
console.log(requestUrl);
|
||||
@@ -118,9 +89,6 @@ export class GenerateImageComponent {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,13 +2,15 @@ import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {tutorialsRouting} from './tutorials.routing';
|
||||
import {TutorialsComponent} from './tutorials.component/tutorials.component';
|
||||
import {MatFormFieldModule} from '@angular/material/form-field';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [
|
||||
tutorialsRouting,
|
||||
TutorialsComponent,
|
||||
CommonModule
|
||||
CommonModule,
|
||||
MatFormFieldModule
|
||||
]
|
||||
})
|
||||
export class TutorialsModule { }
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
<h1 mat-dialog-title>Hi </h1>
|
||||
<div mat-dialog-content >
|
||||
<!--<div mat-dialog-content >-->
|
||||
<mat-dialog-content class="mat-typography">
|
||||
<!-- <mat-nav-list>-->
|
||||
@for (fileInfo of fileInfos; track fileInfo){
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<!-- </mat-nav-list>-->
|
||||
</mat-dialog-content>
|
||||
</div>
|
||||
<!--</div>-->
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button (click)="upload()">Upload</button>
|
||||
<span class="menu-spacer"></span>
|
||||
|
||||
+20
-5
@@ -2,20 +2,30 @@
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.mat-dialog-content{
|
||||
.mat-mdc-list-item{
|
||||
|
||||
}
|
||||
a.mdc-list-item
|
||||
{
|
||||
cursor: grab;
|
||||
height: 120px;
|
||||
padding-bottom: 66px;
|
||||
background-color: rgba(24,255,255,0.04);
|
||||
}
|
||||
/*.mat-dialog-content{
|
||||
min-height: 300px;
|
||||
min-width: 300px;
|
||||
|
||||
height: 75%;
|
||||
width: 75%;
|
||||
}
|
||||
.mdc-dialog--open .mat-mdc-dialog-inner-container
|
||||
}*/
|
||||
/*.mdc-dialog--open .mat-mdc-dialog-inner-container
|
||||
{
|
||||
opacity: 1;
|
||||
width: 600px;
|
||||
}
|
||||
}*/
|
||||
|
||||
.mat-mdc-dialog-container {
|
||||
/*.mat-mdc-dialog-container {
|
||||
width: 600px;
|
||||
height: 500px;
|
||||
display: block;
|
||||
@@ -25,4 +35,9 @@
|
||||
min-width: inherit;
|
||||
max-width: inherit;
|
||||
outline: 0;
|
||||
}*/
|
||||
/*
|
||||
.mat-mdc-dialog-content{
|
||||
overflow: auto;
|
||||
}
|
||||
*/
|
||||
|
||||
+5
-8
@@ -7,8 +7,7 @@ import {
|
||||
MatDialogTitle
|
||||
} from '@angular/material/dialog';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
import {MatListItem, MatNavList} from '@angular/material/list';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {MatListItem} from '@angular/material/list';
|
||||
import {FileInfo} from '../../../models/file-info';
|
||||
import {UserApiService} from '../user-api.service';
|
||||
|
||||
@@ -20,10 +19,7 @@ import {UserApiService} from '../user-api.service';
|
||||
MatButton,
|
||||
MatDialogActions,
|
||||
MatDialogClose,
|
||||
|
||||
MatListItem,
|
||||
MatNavList,
|
||||
|
||||
MatListItem
|
||||
],
|
||||
templateUrl: './dialog-select-image.component.html',
|
||||
styleUrl: './dialog-select-image.component.scss'
|
||||
@@ -42,10 +38,10 @@ export class DialogSelectImageComponent {
|
||||
console.log(data);
|
||||
});
|
||||
}
|
||||
|
||||
//open upload dialog
|
||||
upload() {
|
||||
|
||||
this.uploadClicked.emit();
|
||||
|
||||
}
|
||||
|
||||
onNoClick() {
|
||||
@@ -54,5 +50,6 @@ export class DialogSelectImageComponent {
|
||||
|
||||
select(fileInfo:FileInfo) {
|
||||
this.selectClicked.emit(fileInfo);
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<p>dialog-upload-image.component works!</p>
|
||||
<mat-dialog-content class="mat-typography">
|
||||
|
||||
<app-file-upload #imageUpload (onImageUploaded)="imageUpload_ImageUploaded($event)"></app-file-upload>
|
||||
</mat-dialog-content>
|
||||
<div mat-dialog-actions>
|
||||
|
||||
<button mat-button (click)="openSelectImageDialog()">Select image</button>
|
||||
<span class="menu-spacer"></span>
|
||||
<button mat-button mat-dialog-close (click)="onNoClick()">No Thanks</button>
|
||||
<!-- <button mat-button cdkFocusInitial (click)="select()">Ok</button>-->
|
||||
|
||||
<button mat-button cdkFocusInitial [disabled]="!imageUploaded" (click)="selectUploadedImage()">Ok</button>
|
||||
</div>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
.menu-spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DialogUploadImageComponent } from './dialog-upload-image.component';
|
||||
|
||||
describe('DialogUploadImageComponent', () => {
|
||||
let component: DialogUploadImageComponent;
|
||||
let fixture: ComponentFixture<DialogUploadImageComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [DialogUploadImageComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(DialogUploadImageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
import {Component, EventEmitter, inject, Output, ViewChild} from '@angular/core';
|
||||
import {FileUploadComponent} from '../../../components/file-upload.component/file-upload.component';
|
||||
import {MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef} from '@angular/material/dialog';
|
||||
import {MatButton} from '@angular/material/button';
|
||||
import {FileInfo} from '../../../models/file-info';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dialog-upload-image.component',
|
||||
imports: [
|
||||
FileUploadComponent,
|
||||
MatDialogContent,
|
||||
MatButton,
|
||||
MatDialogActions,
|
||||
MatDialogClose
|
||||
],
|
||||
templateUrl: './dialog-upload-image.component.html',
|
||||
styleUrl: './dialog-upload-image.component.scss'
|
||||
})
|
||||
export class DialogUploadImageComponent {
|
||||
//select uploaded file
|
||||
@Output() selectUploadedImageClicked = new EventEmitter<any>();
|
||||
|
||||
//open select dialog
|
||||
@Output() openSelectDialogClicked = new EventEmitter<any>();
|
||||
|
||||
readonly dialogRef = inject(MatDialogRef<DialogUploadImageComponent>);
|
||||
|
||||
@ViewChild('imageUpload') imageUpload: FileUploadComponent | undefined;
|
||||
|
||||
imageUploaded:boolean = false;
|
||||
|
||||
onNoClick() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
selectUploadedImage() {
|
||||
this.selectUploadedImageClicked.emit(this.imageUpload?.fileInfo?.url);
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
openSelectImageDialog() {
|
||||
this.openSelectDialogClicked.emit();
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
imageUpload_ImageUploaded($event: FileInfo | undefined) {
|
||||
if($event){
|
||||
this.imageUploaded = true;
|
||||
}
|
||||
else{
|
||||
this.imageUploaded = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -14,9 +14,9 @@
|
||||
<img style="width: 120px; height: 120px" src="{{tutorial.titleimage}}" alt="">
|
||||
<input matInput
|
||||
[(ngModel)]="tutorial.titleimage">
|
||||
<button mat-raised-button color="primary" (click)="openSelectImageDialog('100ms', '5ms')">Select image</button>
|
||||
|
||||
</mat-form-field>
|
||||
<button mat-raised-button color="primary" (click)="openSelectImageDialog('100ms', '5ms')">Select image</button>
|
||||
<button mat-raised-button color="primary" (click)="openUploadImageDialog('100ms', '5ms')">Upload image</button>
|
||||
<div class="example-full-width">
|
||||
<mat-label>Description</mat-label>
|
||||
<mat-tab-group>
|
||||
|
||||
+30
-7
@@ -12,10 +12,10 @@ import {MatFormField, MatInput, MatLabel} from '@angular/material/input';
|
||||
import {MatTab, MatTabGroup} from '@angular/material/tabs';
|
||||
import {FormBuilder, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {AngularMarkdownEditorModule, EditorInstance, EditorOption} from 'angular-markdown-editor';
|
||||
import {DialogLoginComponent} from '../../main-module/main.component/dialog-login.component/dialog-login.component';
|
||||
import {GlobalConstants} from '../../../global-constants';
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {DialogSelectImageComponent} from '../dialog-select-image.component/dialog-select-image.component';
|
||||
import {DialogUploadImageComponent} from '../dialog-upload-image.component/dialog-upload-image.component';
|
||||
import {FileUploadComponent} from '../../../components/file-upload.component/file-upload.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tutorial-add.component',
|
||||
@@ -51,6 +51,8 @@ export class TutorialAddComponent implements OnInit{
|
||||
|
||||
readonly dialog = inject(MatDialog);
|
||||
|
||||
|
||||
|
||||
markdown = `## Markdown __rulez__!
|
||||
---
|
||||
|
||||
@@ -72,10 +74,6 @@ const language = 'typescript';
|
||||
constructor(private fb: FormBuilder,
|
||||
private markdownService: MarkdownService,
|
||||
private userApiService: UserApiService,
|
||||
private storageService: TokenStorageService,
|
||||
private eventBusService: EventBusService,
|
||||
private router: Router,
|
||||
private authService: AuthService
|
||||
) {
|
||||
|
||||
this.tutorial.description = this.markdown;
|
||||
@@ -185,7 +183,7 @@ const language = 'typescript';
|
||||
});
|
||||
dialogSelectRef.componentInstance.uploadClicked.subscribe(result => {
|
||||
dialogSelectRef.close();
|
||||
//this.openSignupDialog(enterAnimationDuration, exitAnimationDuration);
|
||||
this.openUploadImageDialog(enterAnimationDuration, exitAnimationDuration);
|
||||
})
|
||||
|
||||
const dialogSelectSubscription = dialogSelectRef.componentInstance.selectClicked
|
||||
@@ -199,4 +197,29 @@ const language = 'typescript';
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
openUploadImageDialog(enterAnimationDuration: string, exitAnimationDuration: string) {
|
||||
let dialogSelectRef = this.dialog.open(DialogUploadImageComponent, {
|
||||
height: '500px',
|
||||
width: '600px',
|
||||
enterAnimationDuration,
|
||||
exitAnimationDuration,
|
||||
// data: {username: this.dialogLoginData.username, password: this.dialogLoginData.password}
|
||||
});
|
||||
dialogSelectRef.componentInstance.openSelectDialogClicked.subscribe(result => {
|
||||
dialogSelectRef.close();
|
||||
this.openSelectImageDialog(enterAnimationDuration, exitAnimationDuration);
|
||||
})
|
||||
|
||||
const dialogUploadSubscription = dialogSelectRef.componentInstance.selectUploadedImageClicked
|
||||
.subscribe(result => {
|
||||
console.log('Got the data!', result);
|
||||
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
this.tutorial.titleimage = result.url;
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {forkJoin, Observable} from 'rxjs';
|
||||
import {Tutorial} from '../../models/tutorial.model';
|
||||
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||
import {HttpClient, HttpEvent, HttpHeaders, HttpRequest} from '@angular/common/http';
|
||||
import {GlobalConstants} from '../../global-constants';
|
||||
import {FileInfo} from '../../models/file-info';
|
||||
|
||||
@@ -15,6 +15,19 @@ export class UserApiService {
|
||||
|
||||
}
|
||||
|
||||
upload(file: File): Observable<HttpEvent<any>> {
|
||||
const formData: FormData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
const req = new HttpRequest('POST', `${this.baseUrl}/upload`, formData, {
|
||||
reportProgress: true,
|
||||
responseType: 'json'
|
||||
});
|
||||
|
||||
return this.http.request(req);
|
||||
}
|
||||
|
||||
|
||||
saveZhipuaiImage(url: string): Observable<any> {
|
||||
return this.http.post(`${this.baseUrl}/saveZhipuAiImage`, {imageUrl:url});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common';
|
||||
import {userRouting} from './user.routing';
|
||||
import {UserComponent} from './user.component/user.component';
|
||||
import {AngularMarkdownEditorModule} from 'angular-markdown-editor';
|
||||
import {MatFormFieldModule} from '@angular/material/form-field';
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +13,8 @@ import {AngularMarkdownEditorModule} from 'angular-markdown-editor';
|
||||
userRouting,
|
||||
UserComponent,
|
||||
CommonModule,
|
||||
AngularMarkdownEditorModule
|
||||
AngularMarkdownEditorModule,
|
||||
MatFormFieldModule
|
||||
]
|
||||
})
|
||||
export class UserModule { }
|
||||
|
||||
Reference in New Issue
Block a user