Skip to content

Commit

Permalink
Basic image history
Browse files Browse the repository at this point in the history
  • Loading branch information
Metal079 committed Mar 12, 2024
1 parent d69827f commit 6f0311f
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 22 deletions.
3 changes: 3 additions & 0 deletions src/_shared/mobians-image.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ export interface MobiansImage {
base64: string;
UUID: string;
rating?: boolean;
timestamp?: Date;
promptSummary?: string;
thumbnailUrl?: string; // Add this line
}

2 changes: 1 addition & 1 deletion src/app/home/image-grid/image-grid.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<img [src]="'data:image/png;base64,' + images[3].base64" class="small-image" alt="Image4 goes here" (click)="inpaintingEnabled || expandImage(3, $event)" id="image3">
</div>
<div class="reference-image" *ngIf="this.sharedService.getReferenceImageValue() && !showLoading && showReferenceImage" id="wrapper5">
<img [src]="this.sharedService.getReferenceImageValue()!.url" alt="Reference Image goes here" (click)="inpaintingEnabled || expandImage(4, $event)" id="referenceImage">
<img [src]="this.sharedService.getReferenceImageValue()!.url ?? this.sharedService.getReferenceImageValue()!.thumbnailUrl" alt="Reference Image goes here" (click)="inpaintingEnabled || expandImage(4, $event)" id="referenceImage">
</div>
<canvas #imageCanvas id="drawing-canvas" (mousedown)="onMouseDown($event)" (mousemove)="onMouseMove($event)" (mouseup)="onMouseUp()"></canvas>

Expand Down
1 change: 1 addition & 0 deletions src/app/home/image-grid/image-grid.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export class ImageGridComponent {
if (image) {
console.log('Reference Image changed:', image);
this.showReferenceImage = true;
this.showInstructions = false;
}
else{
console.log('Reference Image removed');
Expand Down
45 changes: 45 additions & 0 deletions src/app/home/options/options.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,51 @@
margin-left: 10px;
}

.history-panel {
margin-top: 20px;
margin-left: 10px;
}

.history-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
grid-gap: 10px;
margin-top: 10px;
}

.history-item {
cursor: pointer;
}

.history-item img {
width: 100%;
height: auto;
border-radius: 4px;
}

.history-details {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 5px;
}

.summary-text {
max-height: 40px; /* Adjust the height as needed */
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1; /* Adjust the number of lines to show */
-webkit-box-orient: vertical;
text-align: center;
}

.no-images-message {
text-align: center;
padding: 20px;
color: #888;
}

@media (max-width: 480px) {
.input-button-container {
display: flex;
Expand Down
46 changes: 37 additions & 9 deletions src/app/home/options/options.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,47 @@
[(ngModel)]="generationRequest.strength" />
</div>



<!-- Advanced options -->
<div id="advanced-options">
<button class="btn btn-primary dropdown-toggle" data-bs-toggle="collapse" href="#collapseExample" role="button"
aria-expanded="false" aria-controls="collapseExample">
aria-expanded="false" aria-controls="collapseExample" (click)="toggleOptions()">
Options
</button>

<!-- Image History Panel -->
<span class="history-panel">
<button class="btn btn-primary dropdown-toggle" type="button" data-bs-toggle="collapse" data-bs-target="#historyCollapse"
aria-expanded="false" aria-controls="historyCollapse" (click)="toggleHistory()">
Image History
</button>
<div class="collapse" id="historyCollapse">
<div class="card card-body">
<!-- Image History Panel -->
<div class="history-grid">
<div *ngFor="let image of paginatedImages" class="history-item">
<img [src]="image.url ?? image.thumbnailUrl" alt="Generated Image" (click)="openImageDetails(image)">
<div class="history-details">
<span>{{ image.timestamp | date:'short' }}</span>
<span class="summary-text">{{ image.promptSummary }}</span>
</div>
</div>
</div>
<!-- Show message if no images are available -->
<div *ngIf="paginatedImages.length === 0" class="no-images-message">
No generated images available.
</div>
<div class="pagination">
<button class="btn btn-sm btn-primary" (click)="previousPage()" [disabled]="currentPage === 1">Previous</button>
<span>Page {{ currentPage }} of {{ totalPages }}</span>
<button class="btn btn-sm btn-primary" (click)="nextPage()" [disabled]="currentPage === totalPages">Next</button>
</div>
</div>
</div>
</span>


<!-- Remove reference image button -->
<span *ngIf="referenceImage" id="remove-reference-image-button" style="margin-left: 20px;">
<button class="btn btn-danger" type="button" (click)="removeReferenceImage()">
Expand Down Expand Up @@ -180,8 +214,7 @@
</span>
</label>
<input type="text" class="form-control" id="fastPassCode" placeholder="Join the Discord to win!"
[(ngModel)]="generationRequest.fast_pass_code"
(input)="onFastPassCodeChange($event)" />
[(ngModel)]="generationRequest.fast_pass_code" (input)="onFastPassCodeChange($event)" />
</div>

<!-- Notifications -->
Expand All @@ -200,10 +233,5 @@
</div>
</div>

<!-- <p-overlayPanel #op>
<ng-template pTemplate="content">
<h4>Custom Content</h4>
</ng-template>
</p-overlayPanel> -->
<!-- <p-button (click)="op.toggle($event)" icon="pi pi-image" label="Show"></p-button> -->

</div>
175 changes: 163 additions & 12 deletions src/app/home/options/options.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { SwPush } from '@angular/service-worker';
export class OptionsComponent {
private subscription!: Subscription;
private referenceImageSubscription!: Subscription;
private dbName = 'ImageDatabase';
private storeName = 'ImageStore';

models = ["sonicDiffusionV4", "fluffySonic"]
enableGenerationButton: boolean = true;
Expand Down Expand Up @@ -58,6 +60,12 @@ export class OptionsComponent {
currentSeed?: number;
supporter: boolean = false;
serverMember: boolean = false;
userGeneratedImages: MobiansImage[] = [];

paginatedImages: MobiansImage[] = [];
currentPage = 1;
imagesPerPage = 6; // Display 8 images per page (2 rows of 4 images each)
totalPages = 1;

@Input() inpaintMask?: string;

Expand All @@ -78,6 +86,27 @@ export class OptionsComponent {
, private swPush: SwPush
) { }

private openDatabase(): Promise<IDBDatabase> {
return new Promise((resolve, reject) => {
const request = indexedDB.open(this.dbName, 2);

request.onerror = (event) => {
reject(new Error('Failed to open database'));
};

request.onsuccess = (event) => {
const db = request.result;
resolve(db);
};

request.onupgradeneeded = (event) => {
const db = request.result;
db.deleteObjectStore(this.storeName); // Delete the existing object store
db.createObjectStore(this.storeName, { keyPath: 'UUID' }); // Recreate the object store with the correct key path
};
});
}

ngOnInit() {
this.subscription = this.sharedService.getPrompt().subscribe(value => {
this.generationRequest.prompt = value;
Expand Down Expand Up @@ -236,7 +265,7 @@ export class OptionsComponent {
}

// Load session storage info of changed settings
loadSettings() {
async loadSettings() {
if (localStorage.getItem("prompt-input") != null) {
this.generationRequest.prompt = localStorage.getItem("prompt-input")!;
}
Expand All @@ -261,6 +290,44 @@ export class OptionsComponent {
if (localStorage.getItem("model") != null) {
this.generationRequest.model = localStorage.getItem("model")!;
}

try {
const db = await this.openDatabase();
const transaction = db.transaction(this.storeName, 'readonly');
const store = transaction.objectStore(this.storeName);

const request = store.getAll();

request.onsuccess = (event) => {
this.userGeneratedImages = request.result;

// Sort the userGeneratedImages array based on the timestamp in descending order
this.userGeneratedImages.sort((a, b) => {
const timestampA = a.timestamp ? a.timestamp.getTime() : 0;
const timestampB = b.timestamp ? b.timestamp.getTime() : 0;
return timestampB - timestampA;
});

// Calculate the total number of pages
this.totalPages = Math.ceil(this.userGeneratedImages.length / this.imagesPerPage);

// Display the first page of images
this.paginateImages();
};

request.onerror = (event) => {
console.error('Failed to retrieve images from IndexedDB', event);
};

// Wait for the transaction to complete before proceeding
await new Promise((resolve) => {
transaction.oncomplete = () => {
resolve(undefined);
};
});
} catch (error) {
console.error('Failed to open database', error);
}
}

// Reset session storage info of changed settings and reset view
Expand Down Expand Up @@ -376,30 +443,70 @@ export class OptionsComponent {
// Only continue the stream while the job is incomplete
takeWhile(response => !(jobComplete = (response.status === 'completed')), true),
// Once the stream completes, do any cleanup if necessary
finalize(() => {
finalize(async () => {
if (this.enableNotifications) {
this.notificationService.playDing();
this.notificationService.sendPushNotification();
}
if (jobComplete && lastResponse) {
console.log(lastResponse);
this.images = lastResponse.result.map((base64String: string) => {
const generatedImages = lastResponse.result.map((base64String: string) => {
return {
base64: base64String,
// Fill in other properties as needed
width: this.generationRequest.width, // Example value, update as needed
height: this.generationRequest.height, // Example value, update as needed
aspectRatio: this.aspectRatio.aspectRatio, // Example value, update as needed
UUID: uuidv4(), // Example value, update as needed
rated: false, // Example value, update as needed
width: this.generationRequest.width,
height: this.generationRequest.height,
aspectRatio: this.aspectRatio.aspectRatio,
UUID: uuidv4(),
rated: false,
timestamp: new Date(),
promptSummary: this.generationRequest.prompt.slice(0, 50) + '...', // Truncate prompt summary
url: 'data:image/png;base64,' + base64String // Generate URL
};
});
this.images = generatedImages;
this.sharedService.setImages(this.images);

// Add the generated images to userGeneratedImages array
this.userGeneratedImages.push(...generatedImages);

// Sort the userGeneratedImages array based on the timestamp in descending order
this.userGeneratedImages.sort((a, b) => {
const timestampA = a.timestamp ? a.timestamp.getTime() : 0;
const timestampB = b.timestamp ? b.timestamp.getTime() : 0;
return timestampB - timestampA;
});

// Calculate the total number of pages
this.totalPages = Math.ceil(this.userGeneratedImages.length / this.imagesPerPage);

// Display the current page of images
this.paginateImages();

try {
const db = await this.openDatabase();
const transaction = db.transaction(this.storeName, 'readwrite');
const store = transaction.objectStore(this.storeName);

for (const image of generatedImages) {
console.log(image);
store.put(image);
}

transaction.oncomplete = () => {
console.log('Images stored in IndexedDB');
};

transaction.onerror = (event) => {
console.error('Failed to store images in IndexedDB', event);
};
} catch (error) {
console.error('Failed to open database', error);
}

this.loadingChange.emit(false);
this.enableGenerationButton = true;
}
})

)
.subscribe(
response => {
Expand All @@ -416,8 +523,8 @@ export class OptionsComponent {
}
else {
// This will be called every 3 seconds, so we do nothing here
console.log("queue position: " + response.queue_position);
this.queuePositionChange.emit(response.queue_position);
console.log("queue position: " + response.queue_position ?? 0);
this.queuePositionChange.emit(response.queue_position ?? 0);
}
},
error => {
Expand Down Expand Up @@ -472,6 +579,50 @@ export class OptionsComponent {
this.imageModalOpen.emit(true);
}

openImageDetails(image: MobiansImage) {
// Implement the logic to open the image details modal or view
console.log('Opening image details for:', image);

// Set the reference image to the selected image
this.referenceImage = image;
this.generationRequest.image = image.base64;
this.sharedService.setReferenceImage(image);
}

toggleOptions() {
const historyCollapse = document.getElementById('historyCollapse');
if (historyCollapse) {
historyCollapse.classList.remove('show');
}
}

toggleHistory() {
const optionsCollapse = document.getElementById('collapseExample');
if (optionsCollapse) {
optionsCollapse.classList.remove('show');
}
}

paginateImages() {
const startIndex = (this.currentPage - 1) * this.imagesPerPage;
const endIndex = startIndex + this.imagesPerPage;
this.paginatedImages = this.userGeneratedImages.slice(startIndex, endIndex);
}

previousPage() {
if (this.currentPage > 1) {
this.currentPage--;
this.paginateImages();
}
}

nextPage() {
if (this.currentPage < this.totalPages) {
this.currentPage++;
this.paginateImages();
}
}

// Example function called after successful Discord login
onDiscordLoginSuccess(userData: any) {
localStorage.setItem('discordUserData', JSON.stringify(userData));
Expand Down

0 comments on commit 6f0311f

Please sign in to comment.