Skip to content

Commit

Permalink
Added a context menu to show a comic's details [#200]
Browse files Browse the repository at this point in the history
 * Added some additional output to the details dialog.
 * Added a context menu to the covers view.
 * Added a context menu item to show the details dialog.
  • Loading branch information
mcpierce committed Jan 19, 2021
1 parent 16346a5 commit 93dd618
Show file tree
Hide file tree
Showing 20 changed files with 468 additions and 206 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,34 +57,34 @@ public class Comic {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonProperty("id")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private Long id;

@Transient
@JsonProperty("nextIssueId")
@JsonView({View.ComicDetailsView.class})
@JsonView(View.ComicDetailsView.class)
@Getter
@Setter
private Long nextIssueId;

@Transient
@JsonProperty("previousIssueId")
@JsonView({View.ComicDetailsView.class})
@JsonView(View.ComicDetailsView.class)
@Getter
@Setter
private Long previousIssueId;

@Column(name = "filename", nullable = false, unique = true, length = 1024)
@JsonProperty("filename")
@JsonView({View.ComicListView.class, View.PageList.class, View.LibraryUpdate.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private String filename;

@OneToOne(cascade = CascadeType.ALL, mappedBy = "comic", orphanRemoval = true)
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private ComicFileDetails fileDetails;
Expand All @@ -93,49 +93,49 @@ public class Comic {

@Enumerated(EnumType.STRING)
@JsonProperty("archiveType")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private ArchiveType archiveType;

@Column(name = "publisher", length = 128)
@JsonProperty("publisher")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private String publisher;

@Column(name = "series", length = 128)
@JsonProperty("series")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private String series;

@Column(name = "volume", length = 4)
@JsonProperty("volume")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private String volume;

@Column(name = "issue_number", length = 16)
@JsonProperty("issueNumber")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
private String issueNumber;

@Column(name = "imprint")
@JsonProperty("imprint")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private String imprint;

@OneToMany(mappedBy = "comic", cascade = CascadeType.ALL, orphanRemoval = true)
@OrderColumn(name = "page_number")
@JsonProperty("pages")
@JsonView({View.ComicDetailsView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
List<Page> pages = new ArrayList<>();

Expand All @@ -150,15 +150,15 @@ public class Comic {
@ManyToOne
@JoinColumn(name = "scan_type_id")
@JsonProperty("scanType")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private ScanType scanType;

@ManyToOne
@JoinColumn(name = "format_id")
@JsonProperty("format")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private ComicFormat format;
Expand All @@ -176,7 +176,7 @@ public class Comic {
@Column(name = "added_date", updatable = false, nullable = false)
@JsonProperty("addedDate")
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Temporal(TemporalType.TIMESTAMP)
@Getter
@Setter
Expand All @@ -185,7 +185,7 @@ public class Comic {
@Column(name = "deleted_date", updatable = true, nullable = true)
@JsonProperty("deletedDate")
@JsonFormat(shape = Shape.NUMBER)
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Temporal(TemporalType.TIMESTAMP)
@Getter
@Setter
Expand All @@ -194,53 +194,53 @@ public class Comic {
@Column(name = "last_updated_date", updatable = true, nullable = false)
@JsonProperty("lastUpdatedDate")
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Temporal(TemporalType.TIMESTAMP)
@Getter
@Setter
private Date dateLastUpdated = new Date();

@Column(name = "comic_vine_id", length = 16)
@JsonProperty("comicVineId")
@JsonView({View.ComicDetailsView.class})
@JsonView(View.ComicDetailsView.class)
@Getter
@Setter
private String comicVineId;

@Column(name = "cover_date", nullable = true)
@Temporal(TemporalType.DATE)
@JsonProperty("coverDate")
@JsonView({View.ComicDetailsView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private Date coverDate;

@Column(name = "sort_name", length = 128)
@JsonProperty("sortName")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private String sortName;

@Column(name = "title", length = 128)
@JsonProperty("title")
@JsonView({View.ComicDetailsView.class})
@JsonView(View.ComicDetailsView.class)
@Getter
@Setter
private String title;

@Column(name = "description")
@Lob
@JsonProperty("description")
@JsonView({View.ComicDetailsView.class})
@JsonView(View.ComicDetailsView.class)
@Getter
@Setter
private String description;

@Column(name = "notes")
@Lob
@JsonProperty("notes")
@JsonView({View.ComicDetailsView.class})
@JsonView(View.ComicDetailsView.class)
@Getter
@Setter
private String notes;
Expand All @@ -250,7 +250,7 @@ public class Comic {
@CollectionTable(name = "comic_characters", joinColumns = @JoinColumn(name = "comic_id"))
@Column(name = "character_name")
@JsonProperty("characters")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
private List<String> characters = new ArrayList<>();

Expand All @@ -259,7 +259,7 @@ public class Comic {
@CollectionTable(name = "comic_teams", joinColumns = @JoinColumn(name = "comic_id"))
@Column(name = "team_name")
@JsonProperty("teams")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
private List<String> teams = new ArrayList<>();

Expand All @@ -268,7 +268,7 @@ public class Comic {
@CollectionTable(name = "comic_locations", joinColumns = @JoinColumn(name = "comic_id"))
@Column(name = "location_name")
@JsonProperty("locations")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
private List<String> locations = new ArrayList<>();

Expand All @@ -277,42 +277,42 @@ public class Comic {
@CollectionTable(name = "comic_story_arcs", joinColumns = @JoinColumn(name = "comic_id"))
@Column(name = "story_name")
@JsonProperty("storyArcs")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
List<String> storyArcs = new ArrayList<>();

@OneToMany(mappedBy = "comic", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonProperty("credits")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
private Set<Credit> credits = new HashSet<>();

@Formula(
value =
"(SELECT COUNT(*) FROM pages p WHERE p.comic_id = id AND p.hash in (SELECT d.hash FROM blocked_page_hashes d))")
@JsonProperty("blockedPageCount")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
private int blockedPageCount;

@Transient
@JsonProperty("comicVineURL")
@JsonView({View.ComicDetailsView.class})
@JsonView(View.ComicDetailsView.class)
@Getter
@Setter
private String comicVineURL;

@Formula(
"(SELECT COUNT(*) FROM comics c WHERE c.series = series AND c.volume = volume AND c.issue_number = issue_number AND c.cover_date = cover_date)")
@JsonProperty("duplicateCount")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
private Integer duplicateCount;

@ManyToMany(
mappedBy = "comics",
cascade = {CascadeType.ALL})
@JsonProperty("readingLists")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
private Set<ReadingList> readingLists = new HashSet<>();

Expand All @@ -324,7 +324,7 @@ public class Comic {
private List<LastReadDate> lastReadDates = new ArrayList<>();

@Transient
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
@Getter
@Setter
private Date lastRead;
Expand Down Expand Up @@ -382,7 +382,7 @@ public void deletePage(int index) {
* @return the filename
*/
@JsonProperty("baseFilename")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
public String getBaseFilename() {
return FilenameUtils.getName(this.filename);
}
Expand All @@ -408,7 +408,7 @@ public Page getCover() {
* @return <code>true</code> if the file is missing
*/
@JsonProperty("missing")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
public boolean isMissing() {
if (this.backingFile == null) {
this.backingFile = new File(this.filename);
Expand All @@ -425,7 +425,7 @@ public int getIndexFor(Page page) {

@Transient
@JsonProperty("sortableIssueNumber")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
public String getSortableIssueNumber() {
final String result = "00000" + (this.issueNumber != null ? this.issueNumber : "");

Expand Down Expand Up @@ -466,7 +466,7 @@ public Page getPage(int index) {
*/
@Transient
@JsonProperty("pageCount")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
public int getPageCount() {
if (!this.pages.isEmpty()) return this.pages.size();
if (this.calculatedPageCount != null) return this.calculatedPageCount.intValue();
Expand All @@ -475,7 +475,7 @@ public int getPageCount() {

@Transient
@JsonProperty(value = "publishedYear")
@JsonView({View.ComicListView.class, View.SessionUpdateView.class})
@JsonView(View.SessionUpdateView.class)
public int getYearPublished() {
if (this.coverDate != null) {
GregorianCalendar calendar = new GregorianCalendar();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public interface AuditLogEntryList {}
public interface ComicFileList {}

/** Used when retrieving a session update. */
public interface SessionUpdateView {}
public interface SessionUpdateView extends ComicListView {}

/** Uses when viewing the build details for the server. */
public interface BuildDetails {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
[style.height]="'auto'"
[alt]="title"
(click)="onCoverClicked()"
(contextmenu)="onContextMenu($event)"
/>
</div>
<div *ngIf="!!description" [innerHTML]="description"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,25 @@ describe('ComicDetailCardComponent', () => {
});
});
});

describe('showing the context menu', () => {
const XPOS = 1;
const YPOS = 29;
const event = new MouseEvent('testing');

beforeEach(() => {
component.comic = COMIC;
spyOn(event, 'preventDefault');
spyOn(component.showContextMenu, 'emit');
component.onContextMenu({ ...event, clientX: XPOS, clientY: YPOS });
});

it('emits an event', () => {
expect(component.showContextMenu.emit).toHaveBeenCalledWith({
comic: COMIC,
x: `${XPOS}px`,
y: `${YPOS}px`
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { filter } from 'rxjs/operators';
import { LoggerService } from '@angular-ru/logger';
import { ComicSelectEvent } from '@app/core';
import { Comic } from '@app/library';
import { ComicContextMenuEvent } from '@app/library/models/ui/comic-context-menu-event';

@Component({
selector: 'cx-comic-detail-card',
Expand All @@ -50,6 +51,7 @@ export class ComicDetailCardComponent implements OnInit, OnDestroy {
@Input() selected = false;

@Output() selectionChanged = new EventEmitter<ComicSelectEvent>();
@Output() showContextMenu = new EventEmitter<ComicContextMenuEvent>();

displayOptionSubscription: Subscription;

Expand Down Expand Up @@ -78,4 +80,14 @@ export class ComicDetailCardComponent implements OnInit, OnDestroy {
});
}
}

onContextMenu($event: MouseEvent): void {
$event.preventDefault();
this.logger.trace('Showing context menu for comic:', this.comic);
this.showContextMenu.emit({
comic: this.comic,
x: `${$event.clientX}px`,
y: `${$event.clientY}px`
} as ComicContextMenuEvent);
}
}

0 comments on commit 93dd618

Please sign in to comment.