Skip to content

Commit

Permalink
Hodgepodge of small fixes/adjustments
Browse files Browse the repository at this point in the history
* Better MarkerBreakdown JSDoc
* Share logic between MarkerBreakdown.introBuckets() and creditsBuckets()
* Use more efficient cloning in MarkerBreakdown.data()
* Fix SVGHelper JSDoc
* Try to workaround mobile browser address bar height styling issues
* Use replaceWith instead of insertBefore/removeChild in BulkShiftOverlay
* Update .dockerignore to ignore thumbnail cache folder
* Add extensions.json to recommend installing eslint in vscode
  • Loading branch information
danrahn committed Mar 10, 2024
1 parent e1fcaa3 commit 1eb03d2
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 30 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ node_modules
.git

Backup
cache
dist
Logs
Test
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ node_modules/*

# Ignore everything in .vscode, except launch.json
# for running the program/tests in vscode.
.vscode/*
!.vscode/launch.json
.vscode/settings.json

# Ignore the backup database
Backup/*
Expand Down
14 changes: 14 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp

// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"dbaeumer.vscode-eslint",

],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [

]
}
3 changes: 1 addition & 2 deletions Client/Script/BulkShiftOverlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,7 @@ class BulkShiftOverlay {
const container = $('#bulkActionContainer');
const currentNode = $('#resolveShiftMessage');
if (currentNode) {
container.insertBefore(node, currentNode);
container.removeChild(currentNode);
currentNode.replaceWith(node);
return;
}

Expand Down
4 changes: 2 additions & 2 deletions Client/Script/SVGHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ function getPlaceholder() {
/**
* Cache of all icon's that we've retrieved to avoid asking the server
* for the same icon over and over.
* @type {Map<string, SVGElement} */
* @type {Map<string, SVGElement>} */
const svgCache = new Map();

/**
* Keeps track of in-progress requests so when we e.g. add 100 expand/collapse arrows
* at the same time, we only ask the server for it once.
* @type {Map<string, Promise<void>} */
* @type {Map<string, Promise<void>>} */
const svgFetchMap = new Map();

/**
Expand Down
14 changes: 9 additions & 5 deletions Client/Style/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ body {
color: var(--theme-primary);
}

/* Force the vertical scrollbar to always be visible to avoid horizontal shifts when the scrollbar appears/
* disappears. There are some behavioral tradeoffs here (content is slightly off-center when no scrollbar
* is visible, but the lack of shifting wins for me. Also, apply this to #plexFrame instead of body, because
* overriding the body itself will prevent scrolling overlays from having a visible scrollbar. */
#plexFrame {
overflow-y: scroll;
height: 100vh;
scrollbar-width: thin !important;
}
Expand Down Expand Up @@ -726,6 +721,15 @@ input:focus-visible {
#topRightControls {
right: 30px;
}

/* Force the vertical scrollbar to always be visible to avoid horizontal shifts when the scrollbar appears/
* disappears. There are some behavioral tradeoffs here (content is slightly off-center when no scrollbar
* is visible, but the lack of shifting wins for me. Also, apply this to #plexFrame instead of body, because
* overriding the body itself will prevent scrolling overlays from having a visible scrollbar. Only apply it
* to "probably not a phone", since this causes issues with mobile browsers' auto-hiding address bar */
#plexFrame {
overflow-y: scroll;
}
}

@media all and (max-width: 767px) { /* Probably a phone */
Expand Down
47 changes: 28 additions & 19 deletions Shared/MarkerBreakdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class MarkerBreakdown {
constructor() {}

/**
* Retrieve the key representing the given marker number and type.
* @param {number} delta
* @param {string} markerType */
static deltaFromType(delta, markerType) {
Expand All @@ -36,12 +37,14 @@ class MarkerBreakdown {
}

/**
* Return the number of markers represented by the given key.
* @param {number} key */
static markerCountFromKey(key) {
return (key >> CreditsShift) + (key & IntroMask);
}

/**
* Retrieve the key representing the given number of intros and credits.
* @param {number} intros
* @param {number} credits */
static keyFromMarkerCount(intros, credits) {
Expand All @@ -59,9 +62,14 @@ class MarkerBreakdown {
return this;
}

/**
* Return the number of unique marker type combinations for this breakdown.
* E.g. 3 will be returned if 5 episodes have 1 intro and no credits, 10 have
* no intros and 1 credits, and 2 have no intros and no credits. */
buckets() { return Object.keys(this.#counts).filter(c => this.#counts[c] !== 0).length; }

/**
* Retrieve consolidated buckets that don't differentiate between marker types.
* @returns {MarkerBreakdownMap} */
collapsedBuckets() {
/** @type {MarkerBreakdownMap} */
Expand All @@ -86,41 +94,39 @@ class MarkerBreakdown {
}

/**
* Return a breakdown only consisting of intro markers.
* @returns {MarkerBreakdownMap} */
introBuckets() {
/** @type {MarkerBreakdownMap} */
const collapsed = {};
for (const [key, value] of Object.entries(this.#counts)) {
if (value === 0) {
continue;
}

const introKey = this.#ic(key);
collapsed[introKey] ??= 0;
collapsed[introKey] += value;
}

return collapsed;
return this.#buckets(this.#ic);
}

/**
* Return a breakdown only consisting of credits markers.
* @returns {MarkerBreakdownMap} */
creditsBuckets() {
return this.#buckets(this.#cc);
}

/**
* @param {(key: number|string) => number} keyFunc */
#buckets(keyFunc) {
const collapsed = {};
for (const [key, value] of Object.entries(this.#counts)) {
if (value === 0) {
continue;
}

const creditsKey = this.#cc(key);
collapsed[creditsKey] ??= 0;
collapsed[creditsKey] += value;
const typeKey = keyFunc(key);
collapsed[typeKey] ??= 0;
collapsed[typeKey] += value;
}

return collapsed;
}

/** Intro count from key */
#ic(v) { return +v & IntroMask; }
/** Credits count from key */
#cc(v) { return +v >> CreditsShift; }

/**
Expand Down Expand Up @@ -165,11 +171,14 @@ class MarkerBreakdown {
return Object.entries(this.#counts).reduce((acc, kv) => acc + (this.#cc(kv[0]) > 0 ? kv[1] : 0), 0);
}

/** @returns {MarkerBreakdownMap} */
/**
* Retrieve the full breakdown that includes marker type info.
* @returns {MarkerBreakdownMap} */
data() {
// Create a copy by stringifying/serializing to prevent underlying data from being overwritten.
// Create a copy to prevent underlying data from being overwritten.
// Since it's just a number-to-number mapping, the spread operator is sufficient.
this.#minify();
return JSON.parse(JSON.stringify(this.#counts));
return { ...this.#counts };
}

/** Adjust the marker count for an episode that previously had `oldCount` markers
Expand Down

0 comments on commit 1eb03d2

Please sign in to comment.