Skip to content
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

Adding feature star rating to top ribbon #562 #586

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
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,048 changes: 3,730 additions & 2,318 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"trash": "6.1.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "0.1000.0",
"@angular-devkit/build-angular": "^0.1100.0",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind too much, but it's generally better not to change versions and keep a PR focused on one thing.

We could update to Angular 11 in a separate PR 🤝

"@angular/animations": "10.0.9",
"@angular/cdk": "10.1.3",
"@angular/cli": "10.0.0",
Expand Down
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { ShortcutsService } from './components/shortcuts/shortcuts.service';
import { SimilarityService } from './pipes/similarity.service';
import { SourceFolderService } from './components/statistics/source-folder.service';
import { StarFilterService } from './pipes/star-filter.service';
import { StarRatingService } from './pipes/star-rating.service';
import { WordFrequencyService } from './pipes/word-frequency.service';

// Components
Expand Down Expand Up @@ -193,6 +194,7 @@ import { WrapperPipe } from './pipes/wrapper.pipe';
SortingPipe,
SourceFolderService,
StarFilterService,
StarRatingService,
WordFrequencyService,
ImageElementService
],
Expand Down
2 changes: 2 additions & 0 deletions src/app/components/home.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@
[darkMode]="settingsButtons['darkMode'].toggled"
[fileString]="currentClickedItemName"
[folderString]="currentPlayingFolder"
[starRating]="currentStarRating"
[index]="currentIndex"
(onFileWordClicked)="handleFileWordClicked($event)"
(onFolderWordClicked)="handleFolderWordClicked($event)"
(onOpenInExplorer)="openInExplorer()"
Expand Down
20 changes: 13 additions & 7 deletions src/app/components/home.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ import { ResolutionFilterService } from '../pipes/resolution-filter.service';
import { ShortcutsService, CustomShortcutAction } from './shortcuts/shortcuts.service';
import { SourceFolderService } from './statistics/source-folder.service';
import { StarFilterService } from '../pipes/star-filter.service';
import { StarRatingService } from '../pipes/star-rating.service';
import { WordFrequencyService, WordFreqAndHeight } from '../pipes/word-frequency.service';

// Components
import { SortOrderComponent } from './sort-order/sort-order.component';

// Interfaces
import { FinalObject, ImageElement, ScreenshotSettings, ResolutionString } from '../../../interfaces/final-object.interface';
import { FinalObject, ImageElement, ScreenshotSettings, ResolutionString, StarRating } from '../../../interfaces/final-object.interface';
import { ImportStage } from '../../../node/main-support';
import { SettingsObject } from '../../../interfaces/settings-object.interface';
import { SortType } from '../pipes/sorting.pipe';
Expand Down Expand Up @@ -101,7 +102,7 @@ export class HomeComponent implements OnInit, AfterViewInit {
@ViewChild('magicSearch', { static: false }) magicSearch: ElementRef;
@ViewChild('searchRef', { static: false }) searchRef: ElementRef;

@ViewChild(SortOrderComponent) sortOrderRef:SortOrderComponent;
@ViewChild(SortOrderComponent) sortOrderRef: SortOrderComponent;

@ViewChild(VirtualScrollerComponent, { static: false }) virtualScroller: VirtualScrollerComponent;

Expand Down Expand Up @@ -251,6 +252,8 @@ export class HomeComponent implements OnInit, AfterViewInit {

currentClickedItemName = '';
currentPlayingFolder = '';
currentStarRating: StarRating;
currentIndex = 0;
fullPathToCurrentFile = '';

fuzzySearchString = '';
Expand Down Expand Up @@ -358,6 +361,7 @@ export class HomeComponent implements OnInit, AfterViewInit {
public shortcutService: ShortcutsService,
public sourceFolderService: SourceFolderService,
public starFilterService: StarFilterService,
public starRatingService: StarRatingService,
public translate: TranslateService,
public wordFrequencyService: WordFrequencyService,
public zone: NgZone,
Expand Down Expand Up @@ -438,7 +442,7 @@ export class HomeComponent implements OnInit, AfterViewInit {
this.electronService.ipcRenderer.on('file-not-found', (event) => {
this.zone.run(() => {
this.modalService.openSnackbar(this.translate.instant('SETTINGS.fileNotFound'));
})
});
});

// Closing of Window was issued by Electron
Expand Down Expand Up @@ -560,7 +564,7 @@ export class HomeComponent implements OnInit, AfterViewInit {
let somethingDeleted: boolean = false;

this.imageElementService.imageElements
.filter((element: ImageElement) => { return element.inputSource == sourceIndex })
.filter((element: ImageElement) => { return element.inputSource == sourceIndex; })
// notice the loosey-goosey comparison! this is because number ^^ string comparison happening here!
.forEach((element: ImageElement) => {
console.log(element.fileName);
Expand All @@ -580,7 +584,7 @@ export class HomeComponent implements OnInit, AfterViewInit {
// When `watch` folder and `chokidar` detects a file was deleted (can happen when renamed too!)
this.electronService.ipcRenderer.on('single-file-deleted', (event, sourceIndex: number, partialPath: string) => {
this.imageElementService.imageElements
.filter((element: ImageElement) => { return element.inputSource == sourceIndex })
.filter((element: ImageElement) => { return element.inputSource == sourceIndex; })
// notice the loosey-goosey comparison! this is because number ^^ string comparison happening here!
.forEach((element: ImageElement) => {
if (('\\' + partialPath) === path.join(element.partialPath, element.fileName)) {
Expand Down Expand Up @@ -810,7 +814,7 @@ export class HomeComponent implements OnInit, AfterViewInit {
this.resetFinalArrayRef();
} else {
this.newVideoImportTimeout = setTimeout(() => {
this.resetFinalArrayRef()
this.resetFinalArrayRef();
}, 3000);
}
}
Expand Down Expand Up @@ -1017,7 +1021,6 @@ export class HomeComponent implements OnInit, AfterViewInit {
* @param clickedThumbnailIndex an index of the thumbnail clicked
*/
public openVideo(item: ImageElement, clickedThumbnailIndex?: number): void {

if (!this.sourceFolderService.sourceFolderConnected[item.inputSource]) {
console.log('not connected!');
this.modalService.openSnackbar(this.translate.instant('SETTINGS.rootFolderNotLive'));
Expand All @@ -1029,6 +1032,8 @@ export class HomeComponent implements OnInit, AfterViewInit {

this.currentPlayingFolder = item.partialPath;
this.currentClickedItemName = item.cleanName;
this.currentStarRating = item.stars;
this.currentIndex = item.index;
const fullPath = this.filePathService.getPathFromImageElement(item);
this.fullPathToCurrentFile = fullPath;

Expand All @@ -1044,6 +1049,7 @@ export class HomeComponent implements OnInit, AfterViewInit {
} else {
this.electronService.ipcRenderer.send('open-media-file', fullPath);
}

}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/app/components/layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@
}

.top-content-position {
left: 10px;
padding-left: 10px;
position: absolute;
width: 100%;
top: 5px;
}

Expand Down
16 changes: 12 additions & 4 deletions src/app/components/meta/meta.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Subscription, Observable } from 'rxjs';
import { ElectronService } from '../../providers/electron.service';
import { FilePathService } from '../views/file-path.service';
import { ManualTagsService } from '../tags-manual/manual-tags.service';
import { StarRatingService } from '../../pipes/star-rating.service';

import { StarRating, ImageElement } from '../../../../interfaces/final-object.interface';
import { TagEmit, RenameFileResponse } from '../../../../interfaces/shared-interfaces';
Expand Down Expand Up @@ -36,7 +37,7 @@ export class MetaComponent implements OnInit, OnDestroy {
@Input() showVideoNotes: boolean;
@Input() star: StarRating;

@Input() renameResponse: Observable<RenameFileResponse>
@Input() renameResponse: Observable<RenameFileResponse>;

starRatingHack: StarRating;
yearHack: number;
Expand All @@ -55,10 +56,10 @@ export class MetaComponent implements OnInit, OnDestroy {
public imageElementService: ImageElementService,
public manualTagsService: ManualTagsService,
public sanitizer: DomSanitizer,
private starRatingService: StarRatingService,
) { }

ngOnInit() {
this.starRatingHack = this.star;
this.yearHack = this.video.year;

this.renamingWIP = this.video.cleanName; // or should this be video.fileName (without extension!?)
Expand All @@ -79,6 +80,11 @@ export class MetaComponent implements OnInit, OnDestroy {
}
});

this.starRatingService.currentStarRating.subscribe(starRatingList => {
this.star = starRatingList[this.video.index];
this.starRatingHack = starRatingList[this.video.index];
});

}

addThisTag(tag: string) {
Expand Down Expand Up @@ -120,7 +126,9 @@ export class MetaComponent implements OnInit, OnDestroy {
index: this.video.index,
stars: rating
});
}

this.starRatingService.changeStarRating(rating, this.video.index);
}

/**
* Update the FinalArray with the year!
Expand Down Expand Up @@ -213,7 +221,7 @@ export class MetaComponent implements OnInit, OnDestroy {
event.target.blur();
this.renamingWIP = this.video.cleanName;
event.stopPropagation();
this.renameError = false
this.renameError = false;
}

/**
Expand Down
66 changes: 58 additions & 8 deletions src/app/components/top/top.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,62 @@
class="file-container"
[ngClass]="{ 'dark-mode-override': darkMode }"
>
<app-icon class="icon" [icon]="'icon-video-blank'" (click)="openInExplorer()"></app-icon>
<span
*ngFor="let item of fileNameArray"
(click)="fileWordClicked(item)"
class="file-word"
<!-- Star rating -->
<div
class="starRating"
>
{{ item }}
</span>
</div>
<button
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is duplicating the same code as happens in the meta-component so it would be best to just create a new component which will have this chunk in its template, and the setStarRating method in its component.ts file 👍

(click)="setStarRating(1.5)"
class="star-rating"
[ngClass]="{ 'star-lit': starRatingHack > 1 }"
tabindex="-1"
>
<app-icon [icon]="'icon-star'"></app-icon>
</button>
<button
(click)="setStarRating(2.5)"
class="star-rating"
[ngClass]="{ 'star-lit': starRatingHack > 2 }"
tabindex="-1"
>
<app-icon [icon]="'icon-star'"></app-icon>
</button>
<button
(click)="setStarRating(3.5)"
class="star-rating"
[ngClass]="{ 'star-lit': starRatingHack > 3 }"
tabindex="-1"
>
<app-icon [icon]="'icon-star'"></app-icon>
</button>
<button
(click)="setStarRating(4.5)"
class="star-rating"
[ngClass]="{ 'star-lit': starRatingHack > 4 }"
tabindex="-1"
>
<app-icon [icon]="'icon-star'"></app-icon>
</button>
<button
(click)="setStarRating(5.5)"
class="star-rating"
[ngClass]="{ 'star-lit': starRatingHack > 5 }"
tabindex="-1"
>
<app-icon [icon]="'icon-star'"></app-icon>
</button>
</div>

<app-icon class="icon" [icon]="'icon-video-blank'" (click)="openInExplorer()" style="margin-left: 0; "></app-icon>
<div
style="margin-left: 23px; width: 80%;"
>
<span
*ngFor="let item of fileNameArray"
(click)="fileWordClicked(item)"
class="file-word"
>
{{ item }}
</span>
</div>
</div>
33 changes: 28 additions & 5 deletions src/app/components/top/top.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,14 @@

.file-container {
max-height: 20px;
min-width: calc(100vw - 100px);
width: 100%;
overflow: hidden;

.icon-video-blank {
position: absolute;
transform: translate(0, 3px);
}

:nth-child(2) {
margin-left: 23px;
}

.file-word {
color: $gray-80;
cursor: pointer;
Expand All @@ -77,6 +73,33 @@
}
}

.star-rating {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is duplicating the CSS that we already have.
In general it's better to have both locations re-use the same CSS - so that we only need to update it in one place (and the visual style is updated in both locations).
One approach is to take out the star-rating class and put it in its own file, and have both templates point to it.

But it really feels best to just break out the star rating chunk into its own element 👍

background-color: transparent;
border: 0;
cursor: pointer;
fill: yellow;
height: 20px;
margin: 0;
opacity: 0.4;
outline: none;
padding: 0;
stroke: #000000;
stroke-linejoin: round;
stroke-width: 0.3px;
width: 20px;
}

.star-lit {
opacity: 1;
transform: scale(1.5);
}

.starRating {
float: right;
width: 117px;
margin-left: 5px;
}

.dark-mode-override {
& .folder-word {
color: $gray-30;
Expand Down
40 changes: 38 additions & 2 deletions src/app/components/top/top.component.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { ImageElementService } from './../../services/image-element.service';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { StarRating, ImageElement } from '../../../../interfaces/final-object.interface';
import { StarRatingService } from '../../pipes/star-rating.service';

@Component({
selector: 'app-top-component',
templateUrl: './top.component.html',
styleUrls: ['./top.component.scss',
'../../fonts/icons.scss']
})
export class TopComponent {
export class TopComponent implements OnInit {

@Input() darkMode: boolean;
@Input() index: number;

starRatingHack: StarRating;

@Input() set starRating(stars: StarRating) {
this.starRatingHack = stars;
}

constructor(
public imageElementService: ImageElementService,
private starRatingService: StarRatingService,
) { }

ngOnInit() {

this.starRatingService.currentStarRating.subscribe(starRatingList => {
this.starRating = starRatingList[this.index];
this.starRatingHack = starRatingList[this.index];
});

}

// Handle folder input
private _folder = '';
Expand Down Expand Up @@ -52,4 +76,16 @@ export class TopComponent {
this.onOpenInExplorer.emit(true);
}

setStarRating(rating: StarRating): void {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is duplicating setStarRating in the meta-component - so it's a good time to create a new component that will have this functionality 👍 and we can then remove this method from both here and meta-component 👍

if (this.starRatingHack === rating) {
rating = 0.5; // reset to "N/A" (not rated)
}
this.starRatingHack = rating; // hack for getting star opacity updated instantly
this.imageElementService.HandleEmission({
index: this.index,
stars: rating
});

this.starRatingService.changeStarRating(rating, this.index);
}
}
Loading